Django多租户

TL; 博士:有没有办法来覆盖reverse的默认行为?

在我的django项目中,我有很多诸如

  url(r'^\w+/company/', include("company.urls", namespace="company")), 

它允许诸如

 .../companyA/company/ .../companyB/company/ 

这样我就可以使用一个自定义中间件来修改请求,以包含一些基于公司正在使用我的网站的具体细节

这一切工作正常,除了当Django试图破译完整的path与reverse{% url .. %}

它似乎正在返回/x/company/作为正则expression式的默认匹配。 因为django.utils.regex_helper方法的next_char有一个\w映射到x的转义映射

我已经能够覆盖 url标记来replace/x/的正确的公司名称,我想知道是否有类似的事情我可以做,以同样的方式覆盖reverse ,或者我可以做的任何其他事情来解决这个问题?

以前,我在用

 url(r'^(?P<company_name>\w+)/company/', include("company.urls", namespace="company")) 

但这意味着我必须在每个视图中包含一个参数

 def view(request, company_name): ... 

以及将其包括在我所有的其他调用视图(即与{% url %} ),我试图避免。

为了方便使用,Django打包了一个完整的可以完成这个任务的现有django包 。 不过下面是我自己的简单实现


我修改了我的nginx代理configuration使用以下

 server_name ~(?<short_url>\w+)\.domainurl\.com$; ... stuff related to static files here location / { proxy_set_header X-CustomUrl $short_url; .... other proxy settings } 

这样做是在请求头中创build一个variables,然后在Django中使用。 然后,我使用这个variables在一个自定义的中间件中扩展一个请求,引用一个允许它在任何地方使用的模型。

 class CompanyMiddleware(object): def process_request(self, request): if settings.DEBUG: request.company = CompanyClass.objects.get(id=1) return None short_url = request.META.get("HTTP_X_CUSTOMURL") try: company = CompanyClass.objects.get(short_url=short_url) except Model.DoesNotExist: return HttpResponseBadRequest('Company not found') request.company = company return None 

例子:

 www.companya.domainurl.com # short_url is companya test.domainurl.com # short_url is test 

要在一个模板中使用它,必须将上下文处理器添加到settings.py

 TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.media", 'django.core.context_processors.request' # This one in particular )