Django 多租户
Django multi tenancy
Tl;博士:有没有办法覆盖 reverse
的默认行为?
在我的 django 项目中,我有很多 url,例如
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/
替换为正确的公司名称,我想知道是否有类似的事情可以覆盖reverse
以同样的方式,或者我可以做些什么来解决这个问题?
之前,我使用的是
url(r'^(?P<company_name>\w+)/company/', include("company.urls", namespace="company"))
但这意味着我必须在每个视图中包含一个参数
def view(request, company_name):
...
并将其包含在我试图避免的所有其他视图调用中(即使用 {% url %}
)。
为了方便使用,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
}
这样做是在请求 header 中创建一个变量,然后可以在 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
)
Tl;博士:有没有办法覆盖 reverse
的默认行为?
在我的 django 项目中,我有很多 url,例如
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/
替换为正确的公司名称,我想知道是否有类似的事情可以覆盖reverse
以同样的方式,或者我可以做些什么来解决这个问题?
之前,我使用的是
url(r'^(?P<company_name>\w+)/company/', include("company.urls", namespace="company"))
但这意味着我必须在每个视图中包含一个参数
def view(request, company_name):
...
并将其包含在我试图避免的所有其他视图调用中(即使用 {% url %}
)。
为了方便使用,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
}
这样做是在请求 header 中创建一个变量,然后可以在 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
)