我最近开发的电子商务系统具有类似的要求 - 许多实例从同一个项目中运行,几乎可以共享所有内容。以前的系统版本是一堆独立安装(〜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对象中的一些标识片段。 –