Django多租户

时间:2015-04-29 08:31:37

标签: python django django-urls

铊; dr:有没有办法覆盖reverse的默认行为?

在我的django项目中,我有很多网址,例如

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

允许使用

等网址
.../companyA/company/
.../companyB/company/

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

除了当django试图使用reverse{% url .. %}解析完整路径时,这一切都正常。

它似乎正在返回/x/company/作为正则表达式的默认匹配。由于django.utils.regex_helper方法next_char具有\w的转义映射,以映射到x

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

以前,我正在使用

reverse

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

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

除了将其包含在我对该视图的所有其他调用中(即使用def view(request, company_name): ... ),我试图避免这种情况。

1 个答案:

答案 0 :(得分:3)

为了便于使用,Django打包编译为page full of every possible existing django package,可以实现此目的。但是下面是我自己的简单实现

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

server_name ~(?<short_url>\w+)\.domainurl\.com$;

... stuff related to static files here
location / {
        proxy_set_header X-CustomUrl $short_url;
        .... other proxy settings
}

这样做是在请求头中创建一个变量,然后可以在Django中使用。然后,我在自定义中间件中使用此变量来扩展请求,并引用允许其在任何地方使用的模型。

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
)