Skip to main content
 首页 » 编程设计

python之Django:如何设置和更改它正确反射(reflect) url 的语言

2025年04月02日45落叶无声

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')) 
    ) 

我的默认语言是英语。 我的模型对每种语言都有 3 个标题字段。 这是 modeltranslation 包的工作方式,即:

(title_en, title_hu, title_sr_latn)

由于我使用 slug 字段作为 url 中模型实例的 url 表示,因此我的模型类中也相应地为每种语言提供了 3 个 slug 字段。

我看不出我的 url 在匈牙利语中看起来像这样:

127.0.0.1/hu/konyvek/learn-django 

我希望我的网址看起来像这样:

英文网址(我不想为默认语言添加语言前缀!):

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

匈牙利语网址:

127.0.0.1/hu/konyvek/a-gyuruk-ura 

Serbian url(不幸的是,塞尔维亚语前缀看起来非常难看,但这是另一个话题):

127.0.0.1/sr-latn/knjige/gospodar-prstenova 

到目前为止,我找不到任何解决此问题的方法。 很明显,我不能在我的语言中使用这些中的任何一个来切换模板中的“下一个”表单元素的值: {{ request.path }} 或 {{ request.get_absolute_path|slice:'3:' }}

所以我暂时排除了'next'元素。 当我切换语言时,在我的首页上一切正常。 例如,如果我转到书籍页面 (/hu/konyvek/),它会正确显示语言,但如果我想从那里更改为另一种语言,它不会让我这样做。 它只是重新加载当前页面。

有什么建议可以实现吗?

请您参考如下方法:

目前,我找不到任何优雅的方法来解决这个问题。 我现在有一个丑陋的解决方案,它暂时只适用于这个项目,因为它是硬编码的。

我在 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 

但是这个解决方案只解决了我一半的问题。 它正确翻译了 url 的“book/”部分,但 slug 部分 e.i. “指环王/”仍然很老,所以。 django 无法解析 url 路径,因为语言已切换,url 的第一级已更改但 urlconf 中没有这样的东西,例如,e.i. 'konyvek/指环王/'。

我稍微修改了一段代码:

@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 

“幸运的是”,上下文列表有一个名为“book”的对象实例,所以我可以在激活新语言后使用它来选择合适的 Slugfield,然后以反向函数将其转发给 kwargs。

也许更好的选择是编写中间件,然后再编写自定义标签。

无论如何,目前它可以工作,但如果有人为此拥有或找到更好更通用的解决方案,我欢迎。

这个问题没有开箱即用的解决方案,这似乎很奇怪。

但也许我错了,只是找不到它。