Django 多租户 [英] Django multi tenancy

查看:45
本文介绍了Django 多租户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆