如何捕获Django URL模式中的子域?

Jas*_*ion 6 django subdomain django-urls internationalization

我有一个Django应用程序,目前支持多种语言.我想添加子域支持,以便"de.mysite.com"查询德语文章,而"mysite.com"查询英语(默认语言).将有大约20个子域都指向同一个Django应用程序.

我有一个抽象模型,包含我的数据的所有字段和每种语言的派生模型.每种语言都有自己的数据库表,如下所示:

class ArticleBase(models.Model):
    title = models.CharField(max_length=240, unique=True)
    date_added = models.DateField(auto_now_add=True)

    class Meta:
        abstract = True

# This is English, the default.
class Article(ArticleBase):
    pass

class Article_de(ArticleBase):
    pass
Run Code Online (Sandbox Code Playgroud)

我可以得到这样的文章(我今天有这个工作):

def article(request, title, language=None):
    if language:
        mod = get_model('app', 'Article_' + language)
        items = mod.filter(title=title)
    else:
        items = Article.objects.filter(title=title)
Run Code Online (Sandbox Code Playgroud)

这是我当前的网址格式:

url(r'^article/(?P<title>[a-zA-Z_-]+)/$", 'app.views.article', name='article'),
Run Code Online (Sandbox Code Playgroud)

如何解析URL模式中的子域前缀,以便将其传递到文章视图中?或者我在处理视图时是否应该从请求中获取此信息?

EWi*_*Wit 6

django中的URLS无权访问URL的域部分,因此这不是一个选项.在每个视图中手动执行此操作是可行的,但不是那么容易维护.

我认为自定义中间件解决方案可能更好,您检查中间件中的请求标头然后加载适当的语言(或者您替换接受语言标头,让django做它的魔力)

localemiddleware可以使语言可用,然后您可以很容易地根据需要使用通过传递给模型/查询.

此外,如果我可能会问:为什么将每个条目存储在单独的表/模型中?你不能只是在模型中添加语言字段并将所有内容存储在一个表中吗?因为购买20个左右的文章模型比单个模型更难维护.

更新:

我玩了一下,所需的中间件非常简单(尽管我的测试非常有限):

class SubDomainLanguage(object):
    def process_request(self, request):
        try:
            request.session['django_language'] = request.META['HTTP_HOST'].split('.')[0]
        except KeyError:
            pass
Run Code Online (Sandbox Code Playgroud)

是中间件,然后更改设置以包括以下内容:

MIDDLEWARE_CLASSES = (
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'subdomainmiddleware.SubDomainLanguage',
    'django.middleware.locale.LocaleMiddleware',
    ...
)
Run Code Online (Sandbox Code Playgroud)

这样你就可以利用正常的Django内置i18n支持.

在视图中,语言随后可用 request.LANGUAGE_CODE