Django多租户 [英] Django multi tenancy
问题描述
铊; dr:是否有办法覆盖 反向
?
Tl; dr: Is there a way to override the default behaviour of reverse
?
在我的django项目中,我有很多网址,如
In my django project I have alot of urls such as
url(r'^\w+/company/', include("company.urls", namespace="company")),
其中允许使用诸如
.../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
这一切都可以正常,除了当django正在尝试用 reverse
和 {%url ..%}
...
This all works fine except for when django is trying to decipher the full path with reverse
and {% url .. %}
...
似乎将 / x / company /
作为正则表达式的默认匹配。因为 django.utils.regex_helper
方法 next_char
具有 \w
映射到 x
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
url
标签我已经能够覆盖来替换 / x /
具有正确的公司名称,我想知道是否有类似的事情,我可以做,以相同的方式覆盖 reverse
或任何我可以做的事情解决这个问题?
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?
以前,我在使用
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):
...
除了将其包含在我所有的我试图避免的视图的其他调用(即使用 {%url%}
)。
As well as include it in all my other calls to the view (i.e with the {% url %}
) which I am trying to avoid.
推荐答案
为了方便使用,Django软件包编译为页面。但是下面是我自己的简单实现
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
我修改了我的nginx代理配置,使用以下
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
}
这是做什么创建一个请求头中的变量,然后可以在Django中使用。此变量我然后在自定义中间件中使用,以扩展请求,引用模型,允许其在任何地方使用。
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
示例:
www.companya.domainurl.com # short_url is companya
test.domainurl.com # short_url is test
To在模板中使用,必须添加上下文处理器o settings.py
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屋!