Django 多租户 [英] Django multi tenancy
问题描述
Tl;博士:有没有办法覆盖 reverse<的默认行为/code>
?
在我的 django 项目中,我有很多网址,例如
url(r'^w+/company/', include("company.urls", namespace="company")),
允许使用诸如
之类的网址.../companyA/company/.../公司B/公司/
这样我就可以使用自定义中间件来修改请求,以根据使用我网站的公司的情况包含一些特定的详细信息
这一切正常,除了当 django 试图用 reverse
和 {% url .. %}
...
它似乎将 /x/company/
作为正则表达式的默认匹配项返回.因为 django.utils.regex_helper
方法 next_char
有一个转义映射 w
映射到 x
>
url
标签我已经能够覆盖来替换/x/
与正确的公司名称,我想知道是否有类似的事情我可以用同样的方式覆盖 reverse
,或者我可以做的任何其他事情来解决这个问题?
以前,我在使用
url(r'^(?Pw+)/company/', include("company.urls", namespace="company"))
但这意味着我必须在每个视图中包含一个参数
def 视图(请求,公司名称):...
以及将它包含在我试图避免的所有其他视图调用中(即使用 {% url %}
).
为了便于使用,Django 打包成一个页面完整,包含所有可能的现有 django 包,可以实现此目的.然而下面是我自己的简单实现
<小时>我修改了我的 nginx 代理配置以使用以下内容
server_name ~(?w+).domainurl.com$;...这里与静态文件相关的东西地点/{proxy_set_header X-CustomUrl $short_url;.... 其他代理设置}
这样做是在请求标头中创建一个变量,然后可以在 Django 中使用该变量.然后我在自定义中间件中使用这个变量来扩展请求并引用模型,该模型允许它在任何地方使用.
class CompanyMiddleware(object):def process_request(self, request):如果设置.调试:request.company = CompanyClass.objects.get(id=1)返回无short_url = request.META.get("HTTP_X_CUSTOMURL")尝试:公司 = CompanyClass.objects.get(short_url=short_url)除了 Model.DoesNotExist:return HttpResponseBadRequest('找不到公司')request.company = 公司返回无
示例:
www.companya.domainurl.com # short_url 是 companyatest.domainurl.com # short_url 是测试
要在模板中使用它,必须将上下文处理器添加到 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' # 特别是这个)
Tl; dr: Is there a way to override the default behaviour of reverse
?
In my django project I have alot of urls such as
url(r'^w+/company/', include("company.urls", namespace="company")),
Which allows for urls such as
.../companyA/company/
.../companyB/company/
So that I can then use a custom middleware to modify the request to include some specific details based upon what company is using my site
This all works fine except for when django is trying to decipher the full path with reverse
and {% url .. %}
...
It seems to be returning /x/company/
as a default match for the regex. since the django.utils.regex_helper
method next_char
has an escape mapping for w
to map to x
The url
tag I have been able to override to replace the /x/
with the correct company name and I am wondering if there is a similar thing I can do to override reverse
in the same way, or anything else that I can do to resolve this problem?
Previously, I was using
url(r'^(?P<company_name>w+)/company/', include("company.urls", namespace="company"))
But this meant I had to include a parameter in every view
def view(request, company_name):
...
As well as include it in all my other calls to the view (i.e with the {% url %}
) which I am trying to avoid.
For ease of use, Django packages as compiled a page full of every possible existing django package that can accomplish this. However below is my own simple implementation
I modified my nginx proxy config to use the following
server_name ~(?<short_url>w+).domainurl.com$;
... stuff related to static files here
location / {
proxy_set_header X-CustomUrl $short_url;
.... other proxy settings
}
What this does is create a variable inside a request header that can then be used within Django. This variable I then used within a custom middleware to extend a request with a reference to the model which allows its use anywhere.
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
Examples:
www.companya.domainurl.com # short_url is companya
test.domainurl.com # short_url is test
To use this within a template, context processors must be added to the 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
)
这篇关于Django 多租户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!