【问题标题】:Django session translation setting is sticky for all languages, except Chinese?django会话翻译设置对所有语言都有粘性,除了中文?
【发布时间】:2017-01-02 19:52:12
【问题描述】:

我遇到了一个从未见过的非常奇怪的问题。我正在使用 Django 1.10。

我有几个字典文件:

/locale/fr/LC_MESSAGES/django.po
/locale/de/LC_MESSAGES/django.po
/locale/zh/LC_MESSAGES/django.po

应用程序字符串是用英文编写的。字典文件完整,编译成mo文件。

我将每个用户的语言偏好存储在UserProfilelanguage 字段中。在更新他们的个人资料时,我将语言翻译应用于会话。

# 'up' is a UserProfile object pertaining to the user
up.update(language=form.cleaned_data['language'])
translation.activate(up.language)
self.request.session[translation.LANGUAGE_SESSION_KEY] = up.language
return super(self, UpdateUserProfile).form_valid(form)

这适用于法语和德语。 return super 以法语/德语呈现表单模板,然后我可以导航到其他页面并查看法语/德语文本。

它不适用于中文(语言代码'zh')。 return super 页面以中文呈现表单模板(我已经在保存后验证了 shell 中的语言设置),但与法语和德语不同的是,当我离开时,所有其他页面都会恢复为英语。

我已经重新启动了开发服务器,以防万一它是由于旧设置造成的。我已经在一个新的、隔离的开发虚拟机上对该分支进行了干净的拉取尝试。在这两种情况下,我对中文都有同样的问题。什么可能导致此错误?

编辑 - 附加信息:

来自 settings.py

LANGUAGE_CODE = 'en-us'
LOCALE_PATHS = [ 
    BASE_DIR + '/locale/',
]
USE_I18N = True
USE_L10N = True

如前所述,在更新语言FormView 的 POST 上,request.session[translation.LANGUAGE_SESSION_KEY] 代码设置为zh,页面显示为中文。在对同一视图的 GET 请求中,页面以英文显示(但检查 request.session[translation.LANGUAGE_SESSION_KEY] 显示它已设置为 zh,尽管显示的是英文文本)。

我没有在网址中使用语言前缀。

【问题讨论】:

  • 您在 Django 设置中设置了哪些语言设置?您是否在您的网址中使用语言前缀?您是否跟踪了会话中存储的值?在后续请求中,request.session[translation.LANGUAGE_SESSION_KEY] 的值是否正确?使用此信息编辑问题。
  • @Louis 感谢您的建议,我已经更新了信息。

标签: python django gettext django-i18n


【解决方案1】:

您已经正确地inferred 认为zh 不是默认LANGUAGES 设置的一部分,因此无法正常工作。

你在制作首页的时候有中文是因为你打了一个相当于translation.activate("zh")的电话。此调用不检查LANGUAGES。它盲目地激活语言zh 的翻译。如果文件存在“zh”,则没有问题。你可以做translation.activate("turnip"),只要存在“萝卜”语言的文件,Django 就可以了..

它对后续页面请求不起作用的原因是 locale middleware 确实检查 LANGUAGES 并拒绝未在此处列出的值:它切换回您配置的默认语言为您的网站。

下面是说明这两种情况的代码:

import os

import django
from django.utils.translation import trans_real as translation, LANGUAGE_SESSION_KEY
from django.middleware.locale import LocaleMiddleware

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "btw.settings")
django.setup()

#
# Calling translation.activate directly.
#
translation.activate("zh")
value = translation._active.value
print "translation:", value.language()

#
# Middleware processing
#
class FakeRequest(object):

    path_info = ""
    session = {}
    COOKIES = {}
    META = {}

middleware = LocaleMiddleware()

for lang in ("fr", "zh", "zh-hans"):
    print "Trying:", lang
    request = FakeRequest()
    request.session[LANGUAGE_SESSION_KEY] = lang

    middleware.process_request(request)
    print request.LANGUAGE_CODE

您将在使用中间件的第二部分中看到,当您选择“zh”作为语言时,request.LANGUAGE_CODE 被设置为您网站的默认语言,而不是“zh”或它的某种变体。在我的系统上,输出是:

translation: zh
Trying: fr
fr
Trying: zh
en-us
Trying: zh-hans
zh-hans

【讨论】:

  • 这是否意味着我应该makemessages -l zh-hans 使用实际的语言代码?目前,我使用-l zh 制作了我的中文字典文件并将LANGUAGE_SESSION_KEY 设置为不匹配的zh-hans 正在捡起它 - 为什么会这样?
  • 这是因为逻辑是这样的,它会为整个语言代码查找一组文件,如果找不到,它会在破折号处截断并重试。因此,如果它找不到zh-hans 的文件但存在zh 的文件,它将使用后者。您可以通过调用trans_real 包中的check_for_language 函数来检查这一点。如果你用像en-potato 这样明显荒谬的值来调用它,它会报告该语言存在,因为它有en。直接拨打gettext.find也可以看到路径。 (例子见check_for_language的代码)
  • 归根结底,我想要zh-hanszh-hant 的不同文件。这不是 Django 的东西,而是这两个选项代表什么:zh-hans 是简体中文。 zh-hant 是繁体中文。不同的是,在简化中,一些字符是不同的。不同地区的人们使用繁体或简体。您可能想在互联网上搜索以传统方式长大的人们对简体中文的看法,并在此基础上决定您应该同时支持还是只支持简体中文。
【解决方案2】:

哇,django调试工具栏的所有调试输出都表明我做对了,所以我查看了global_settings.py的源代码

zh 实际上不是有效的语言代码。您必须在简化的zh-hans 和传统的zh-hant 之间进行选择,而且在设置会话语言后页面奇怪地以中文呈现为 HttpResponse 的事实让我觉得问题出在会话上,而不是设置上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-28
    • 2020-10-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 2019-09-22
    • 2021-11-19
    相关资源
    最近更新 更多