7

我有一个当前支持多种语言的 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

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

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)

这是我当前的 URL 模式:

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

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

4

3 回答 3

10

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

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

localemiddleware可以使语言可用,然后您可以根据需要轻松使用该语言传递给模型/查询。

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

更新:

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

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

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

MIDDLEWARE_CLASSES = (
    ...
    'django.contrib.sessions.middleware.SessionMiddleware',
    'subdomainmiddleware.SubDomainLanguage',
    'django.middleware.locale.LocaleMiddleware',
    ...
)

这样你就可以利用普通的 Django 内置 i18n 支持。

然后在视图中可以使用语言request.LANGUAGE_CODE

于 2013-10-15T15:47:29.067 回答
0

我有一个案例,我有带有句点的子域,例如1.2.3.mydomain.net. 我知道我的域并在我的 local_settings.py 中将其设置为:

DOMAIN = 'EXAMPLE.net'
TEST_SUBDOMAINS = ["127.0.0.1", "localhost", "testserver"]

然后,我检查是否出于测试目的我不做任何事情。之后,我得到我的子域如下:

if (DOMAIN in TEST_SUBDOMAINS):
    return HttpResponse("test only")
subdomain = request.META['HTTP_HOST'].replace((DOMAIN), "")[:-1] 
# -1 is to remove the trailing "." from the subdomain
if subdomain and subdomain != "www" :
# whatever you need...
于 2015-01-20T16:41:27.510 回答
0

您可以使用这个易于使用的 django-subdomains库。它还支持基于子域的 URL 路由和反向。

于 2016-06-30T11:52:08.463 回答