Django 会话翻译设置对所有语言都是粘性的,除了中文?
Django session translation setting is sticky for all languages, except Chinese?
我有一个以前从未见过的非常奇怪的问题。我正在使用 Django 1.10。
我有几个字典文件:
/locale/fr/LC_MESSAGES/django.po
/locale/de/LC_MESSAGES/django.po
/locale/zh/LC_MESSAGES/django.po
应用程序字符串是用英文编写的。词典文件已完成,并编译为 mo
个文件。
我将每个用户的语言偏好存储在 UserProfile
的 language
字段中。更新他们的个人资料时,我将语言翻译应用于会话。
# '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
在 French/German 中呈现表单模板,然后我可以导航到其他页面并查看 French/German 文本。
它不适用于中文(语言代码'zh')。 return super
页面以中文呈现表单模板(我在保存后验证了 shell 中的语言设置),但与法语和德语不同,当我离开时,所有其他页面都恢复为英语.
我已经重新启动了开发服务器,以防它是由于旧设置造成的。我已经在一个新的、独立的开发虚拟机上对该分支进行了干净的拉取。在这两种情况下,我对中文都有同样的问题。什么可能导致此错误?
编辑 - 附加信息:
来自settings.py
LANGUAGE_CODE = 'en-us'
LOCALE_PATHS = [
BASE_DIR + '/locale/',
]
USE_I18N = True
USE_L10N = True
如前所述,在 POST 上,UpdateLanguage FormView
的 request.session[translation.LANGUAGE_SESSION_KEY]
代码设置为 zh
,页面以中文显示。在对同一视图的 GET 请求中,页面以英文显示(但是检查 request.session[translation.LANGUAGE_SESSION_KEY]
显示它设置为 zh
,尽管显示英文文本)。
我没有在网址中使用语言前缀。
哇,django 调试工具栏的所有调试输出表明我做的是正确的,所以我查看了 global_settings.py
的源代码
zh
实际上不是有效的语言代码。您必须在简体 zh-hans
和繁体 zh-hant
之间做出选择,而且在设置会话语言后,HttpResponse 页面以中文奇怪地呈现这一事实让我觉得问题出在会话上,而不是设置。
您 正确 zh
不是默认 LANGUAGES
设置的代码,因此无法正常工作。
你生成第一页时出现中文的原因是你调用了等同于translation.activate("zh")
的调用。此调用不检查 LANGUAGES
。它盲目地激活语言 zh
的翻译。如果 "zh" 的文件在那里,那没有问题。你可以做 translation.activate("turnip")
,只要语言 "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
您将在第二部分使用中间件看到,当您将 select "zh" 作为语言时,request.LANGUAGE_CODE
将设置为您网站的默认语言,而不是"zh" 或它的一些变体。在我的系统上,输出是:
translation: zh
Trying: fr
fr
Trying: zh
en-us
Trying: zh-hans
zh-hans
我有一个以前从未见过的非常奇怪的问题。我正在使用 Django 1.10。
我有几个字典文件:
/locale/fr/LC_MESSAGES/django.po
/locale/de/LC_MESSAGES/django.po
/locale/zh/LC_MESSAGES/django.po
应用程序字符串是用英文编写的。词典文件已完成,并编译为 mo
个文件。
我将每个用户的语言偏好存储在 UserProfile
的 language
字段中。更新他们的个人资料时,我将语言翻译应用于会话。
# '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
在 French/German 中呈现表单模板,然后我可以导航到其他页面并查看 French/German 文本。
它不适用于中文(语言代码'zh')。 return super
页面以中文呈现表单模板(我在保存后验证了 shell 中的语言设置),但与法语和德语不同,当我离开时,所有其他页面都恢复为英语.
我已经重新启动了开发服务器,以防它是由于旧设置造成的。我已经在一个新的、独立的开发虚拟机上对该分支进行了干净的拉取。在这两种情况下,我对中文都有同样的问题。什么可能导致此错误?
编辑 - 附加信息:
来自settings.py
LANGUAGE_CODE = 'en-us'
LOCALE_PATHS = [
BASE_DIR + '/locale/',
]
USE_I18N = True
USE_L10N = True
如前所述,在 POST 上,UpdateLanguage FormView
的 request.session[translation.LANGUAGE_SESSION_KEY]
代码设置为 zh
,页面以中文显示。在对同一视图的 GET 请求中,页面以英文显示(但是检查 request.session[translation.LANGUAGE_SESSION_KEY]
显示它设置为 zh
,尽管显示英文文本)。
我没有在网址中使用语言前缀。
哇,django 调试工具栏的所有调试输出表明我做的是正确的,所以我查看了 global_settings.py
的源代码zh
实际上不是有效的语言代码。您必须在简体 zh-hans
和繁体 zh-hant
之间做出选择,而且在设置会话语言后,HttpResponse 页面以中文奇怪地呈现这一事实让我觉得问题出在会话上,而不是设置。
您 zh
不是默认 LANGUAGES
设置的代码,因此无法正常工作。
你生成第一页时出现中文的原因是你调用了等同于translation.activate("zh")
的调用。此调用不检查 LANGUAGES
。它盲目地激活语言 zh
的翻译。如果 "zh" 的文件在那里,那没有问题。你可以做 translation.activate("turnip")
,只要语言 "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
您将在第二部分使用中间件看到,当您将 select "zh" 作为语言时,request.LANGUAGE_CODE
将设置为您网站的默认语言,而不是"zh" 或它的一些变体。在我的系统上,输出是:
translation: zh
Trying: fr
fr
Trying: zh
en-us
Trying: zh-hans
zh-hans