我最近開發的電子商務系統具有類似的要求 - 許多實例從同一個項目中運行,幾乎可以共享所有內容。以前的系統版本是一堆獨立安裝(〜30),所以它很難維護。我相信這些要求仍然與您的要求不同(例如,所有實例在我的案例中共享相同的模型),但分享我的經驗仍然可能有用。
你說的對,Django並沒有像這樣開箱即可,但實際上它實際上很容易實現。這裏是我做了什麼的簡要描述。
我可以看到我想要實現的和django.contrib.sites
之間的協同作用。另外,因爲許多第三方Django應用程序都知道如何使用它並使用它,例如,爲當前網站生成絕對URL。 sites
的主要問題在於,它希望您指定settings.SITE_ID
中的當前網站ID,這是對多主機問題非常天真的方法。您自然需要什麼以及您還提到的是從Host
請求標頭中確定當前網站。爲了解決這個問題,我借用了django-multisite
:https://github.com/shestera/django-multisite/blob/master/multisite/threadlocals.py#L19
接下來我創建了一個應用程序,封裝了與我的項目的多主機方面相關的所有功能。在我的情況下,該應用程序被稱爲stores
,其中包括兩個重要的類別:stores.middleware.StoreMiddleware
和stores.models.Store
。
模型類是django.contrib.sites.models.Site
的子類。關於繼承Site
的好處是,您可以將Store
傳遞給預期爲Site
的任何函數。因此,您仍然只是使用舊的,有據可查的和經過測試的sites
框架。對於Store
類,我添加了配置所有不同存儲所需的所有字段。所以它有像urlconf
,theme
,robots_txt
和whatnot字段。
中間件類的功能是將Host
標頭與數據庫中相應的Store
實例相匹配。一旦找到匹配的Store
,它將以類似於https://github.com/shestera/django-multisite/blob/master/multisite/middleware.py的方式修補SITE_ID
。另外,它查看了store
的urlconf
,如果它不是None,它將設置request.urlconf
以應用其特殊的URL要求。之後,當前的Store
實例被存儲在request.store
中。這已經被證明是非常有用的,因爲我能夠做這樣的事情在我的觀點:
def homepage(request):
featured = Product.objects.filter(featured=True, store=request.store)
...
request.store
成爲整個項目對我來說request
對象的自然額外維度。
這是在Store
類中定義爲另一件事的功能get_absolute_url
它的實現看起來大致是這樣的:
def get_absolute_url(self, to='/'):
"""
Return an absolute url to this `Store` or to `to` on this store.
The URL includes http:// and the domain name of the store.
`to` can be an object with `get_absolute_url()` or an absolute path as string.
"""
if isinstance(to, basestring):
path = to
elif hasattr(to, 'get_absolute_url'):
path = to.get_absolute_url()
else:
raise ValueError(
'Invalid argument (need a string or an object with get_absolute_url): %s' % to
)
url = 'http://%s%s%s' % (
self.domain,
# This setting allowed for a sane development environment
# where I just set it to ".dev:8000" and configured `dnsmasq`.
# The same value was also removed from the `Host` value in the middleware
# before looking up the `Store` in database.
settings.DOMAIN_SUFFIX,
path
)
return url
所以,我可以很容易地生成URL對象上的其他比目前的專賣店,例如:
# Redirect to `product` on `store`.
redirect(store.get_absolute_url(product))
這基本上是我所需要的一切,以便能夠實現一個系統,允許用戶通過Django管理員在其自己的域中創建一個新的電子商店。
這不正是*網站的貢獻是什麼? –
這些網站contrib假定所有網站都在同一個數據庫上,併爲每個模型添加一個外鍵。此外,它不包括我爲每個網站定製模板的要求。 –
當然可以。您可以在模板路徑中使用Site對象中的一些標識片段。 –