简体   繁体   English

Django:如何设置和更改正确反映网址的语言?

[英]Django: How to set and change languages that it reflects urls properly?

settings.py:
INSTALLED_APPS = [
    ...,
    'modeltranslation',
]
TIME_ZONE = 'Europe/Belgrade'
USE_I18N = True
USE_L10N = True
USE_TZ = True
LANGUAGES = (
    ('en-us', _('English')),
    ('hu', _('Hungarian')),
    ('sr-latn', _('Serbian')),
)
LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
    os.path.join(BASE_DIR, 'books', 'locale'),
)

urls.py:
urlpatterns = [
    url(r'^i18n/', include('django.conf.urls.i18n')),
    ]
urlpatterns += i18n_patterns(
    url(_r('^books/'), include('books.urls', namespace='books'))
    )

My default language is english.我的默认语言是英语。 My model has 3 title fields for each language.我的模型对每种语言都有 3 个标题字段。 It is how modeltranslation package works ie:这就是模型翻译包的工作方式,即:

(title_en, title_hu, title_sr_latn) (title_en, title_hu, title_sr_latn)

Since I use slug field for url representation of an instance of the model in the url, I have 3 slug fileds for each language accordingly in my model class too.由于我使用 slug 字段来表示 url 中模型实例的 url 表示,因此我的模型类中也相应地为每种语言设置了 3 个 slug 文件。

I don't see any sence that my url should look something like this on hungarian for example:我没有看到我的 url 在匈牙利语中应该看起来像这样的任何感觉,例如:

127.0.0.1/hu/konyvek/learn-django

I want my urls to look like this:我希望我的网址看起来像这样:

English url (I don't want to have language prefix for the default language!):英文网址(我不想有默认语言的语言前缀!):

127.0.0.1/books/the-lord-of-the-rings

Hungarian url :匈牙利网址

127.0.0.1/hu/konyvek/a-gyuruk-ura

Serbian url (it is unfortunate that serbian language prefix looks extreamly ugly but that is another topic):塞尔维亚语 url (不幸的是,塞尔维亚语前缀看起来非常难看,但这是另一个话题):

127.0.0.1/sr-latn/knjige/gospodar-prstenova

I couldn't find anything so far that solves this problem.到目前为止,我找不到任何解决此问题的方法。 It is obvious that I can't use either of these in my language switching 'next' form element's value in template: {{ request.path }} or {{ request.get_absolute_path|slice:'3:' }}很明显,我不能在模板中的语言切换“下一个”表单元素的值中使用其中任何一个: {{ request.path }}{{ request.get_absolute_path|slice:'3:' }}

So I excluded the 'next' element temporarily.所以我暂时排除了“下一个”元素。 When I'm switching languages, on my front page everything works well.当我切换语言时,在我的首页上一切正常。 If I go to a books page for example (/hu/konyvek/) , it shows the language properly but if I want from there to change to a different language it doesn't let me do it.例如,如果我转到书籍页面(/hu/konyvek/) ,它会正确显示语言,但是如果我想从那里更改为其他语言,它不会让我这样做。 It just reloads the current page.它只是重新加载当前页面。

Any suggestion how to accomplish this?任何建议如何实现这一点?

For now, I couldn't find any elegant way of solving this problem.目前,我找不到任何优雅的方法来解决这个问题。 I have now an ugly solution that works temporarily and only on this project, because it is hard-coded.我现在有一个丑陋的解决方案,它暂时只适用于这个项目,因为它是硬编码的。

I found this code at https://djangosnippets.org/snippets/2875/我在https://djangosnippets.org/snippets/2875/找到了这个代码

@register.simple_tag(takes_context=True)
def change_lang(context, lang=None, *args, **kwargs):
    path = context['request'].path
    url_parts = resolve( path )

    cur_language = get_language()

    try:
        activate(lang)
        url = reverse( url_parts.view_name, kwargs=url_parts.kwargs )
    finally:
        activate(cur_language)


    return "%s" % url

But this solution solved only half of my problem.但是这个解决方案只解决了我一半的问题。 It took the translation of the 'book/' part of the url correctly, but the slug part ei 'the-lord-of-the-rings/' remained old, so.它正确地翻译了 url 的“book/”部分,但是 slug 部分 ei 'the-lord-of-the-rings/' 仍然很旧,所以。 django couldn't resolve the url path because language was switched, first level of the url is changed but there is no such a thing in urlconf like, ei 'konyvek/the-lord-of-the-rings/'. django 无法解析 url 路径,因为语言已切换,url 的第一级已更改,但 urlconf 中没有这样的东西,例如 ei 'konyvek/the-lord-of-the-rings/'。

I have changed a code a little bit:我稍微改变了一个代码:

@register.simple_tag(takes_context=True)
def change_lang(context, lang=None, *args, **kwargs):

    path = context['request'].path
    url_parts = resolve(path)

    cur_language = get_language()

    try:
        translation.activate(lang)
        if 'book' in context:
            slug = context['book'].slug
            url = reverse(url_parts.view_name, kwargs={'slug': slug})
        else:
            url = reverse(url_parts.view_name, kwargs=url_parts.kwargs)
    finally:
        translation.activate(cur_language)

    return '%s' % url

"Luckily", context list has the object instance called 'book', so I could use it to choose the appropriate Slugfield after I activated the new language then forwarded it to kwargs in reverse function. “幸运的是”,上下文列表有一个名为“book”的对象实例,所以我可以在激活新语言后使用它来选择合适的 Slugfield,然后在反向函数中将它转发给 kwargs。

Maybe better choice would be to write middleware then custom tag.也许更好的选择是编写中间件然后自定义标签。

Anyway, for now it works, but I welcome if anyone has or finds much nicer and general solution for this.无论如何,现在它有效,但我欢迎如果有人有或找到更好的和通用的解决方案。

It seems very strange the there is no out of the box solution for this problem.这个问题没有现成的解决方案,这似乎很奇怪。

But maybe I'm wrong and just can't find it.但也许我错了,只是找不到它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM