Python Django会话翻译设置对于所有语言都是粘性的,除了中文?

Python Django会话翻译设置对于所有语言都是粘性的,除了中文?,python,django,gettext,django-i18n,Python,Django,Gettext,Django I18n,我有一个从未见过的奇怪问题。我使用的是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 Use

我有一个从未见过的奇怪问题。我使用的是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
以法语/德语呈现表单模板,然后我可以导航到其他页面并查看法语/德语文本

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

我重新启动了dev服务器,以防它是由于旧设置引起的。我已经在一个新的、隔离的dev虚拟机上对该分支进行了测试。在这两种情况下,我对中国人都有同样的问题。什么可能导致此错误

编辑-其他信息: 从settings.py

LANGUAGE_CODE = 'en-us'
LOCALE_PATHS = [ 
    BASE_DIR + '/locale/',
]
USE_I18N = True
USE_L10N = True
如前所述,在UpdateLanguage
FormView
的帖子中,
请求会话[translation.LANGUAGE\u session\u KEY]
代码设置为
zh
,页面以中文显示。在对同一视图的GET请求中,页面以英文显示(但是检查
request.session[translation.LANGUAGE\u session\u KEY]
显示,尽管显示英文文本,页面仍设置为
zh


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

哇,django调试工具栏的所有调试输出都表明我做了正确的事情,所以我查看了

zh
实际上不是有效的语言代码。您必须在简体的
zh hans
和繁体的
zh hant
之间进行选择,而且设置会话语言后,HttpResponse的中文页面呈现得很奇怪,这让我觉得会话有问题,不是设置。

您正确地知道,
zh
不是默认
语言设置的一部分,因此无法正常工作

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

它在后续页面请求中不起作用的原因是它确实会检查
语言
,并拒绝未列出的值:它会切换回您为站点配置的默认语言

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

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

您在Django设置中设置了什么语言设置?您是否在URL中使用语言前缀?您是否跟踪了会话中存储的值?在后续请求中,
request.session[translation.LANGUAGE\u session\u KEY]
的值是否正确?用这些信息编辑问题。@Louis谢谢你的建议,我已经更新了信息。这是否意味着我应该用实际的语言代码
makemessages-l zh hans
?目前,我使用
-l zh
制作了我的中文字典文件,并将
语言会话键设置为不匹配的
zh hans
正在拾取它-为什么会这样?因为逻辑是这样的,它会为整个语言代码查找一组文件,如果找不到,它会在破折号处截断并重试。因此,如果它找不到
zh hans
的文件,但存在
zh
的文件,它将使用后者。您可以通过调用
trans\u real
包中的
check\u for\u language
函数来检查这一点。如果您用一个明显荒谬的值调用它,比如
en-potato
,它将报告该语言的存在,因为它有
en
。如果直接调用
gettext.find
,也可以看到路径。(例如,请参阅
check_for_language
的代码。)在一天结束时,我希望
zh hans
zh hant
有不同的文件。这不是Django的东西,而是两个选项所代表的:
zh hans
是简体中文
zh hant
是繁体中文。不同之处在于,在简体字中,有些字符是不同的。不同地区的人们使用传统的或简化的语言。你可能想在互联网上搜索一下在传统基础上长大的人们对简体中文的看法,并据此决定是支持两者,还是只支持简体中文。