1. 配置

很多不靠谱的文章上来第一步就是设置LANGUAGE_CODE = 'zh-CN',这明显是没看懂配置项的意思,从Django文档可以看出, LANGUAGE_CODE只是最后的兜底设置 ,所以这一步的设置完全没有必要,当然,如果站点确定只提供一种语言的服务,则需要设置并且不提供其他语言的翻译。

然后就是USE_I18NLocaleMiddleware的配置了, 如果要提供两种语言以上的服务,那么必须设置USE_I18N=True并且配置LocaleMiddleware LocaleMiddleware尽可能在其他中间件之前但必须在SessionMiddlewareCacheMiddleware之后,可能是这样的

1
2
3
4
5
MIDDLEWARE = [
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
]

USE_L10N是指用来配置诸如时间格式、数字格式(有没有千分位符号)等,跟多语言是没有直接关系的 ,主要设置项可以参考文档或者源代码django.utils.formats.FORMAT_SETTINGS中的key值。

另外,如果翻译的文件不是在INSTALLED_APPS中的app的locale目录下,那么需要修改LOCALE_PATHS配置,让Django能够找到.mo文件。

2. Django如何确定使用那种语言

how-django-discovers-language-preference已经介绍的很详细了,各种方式有不同的优先级,根据需要选择就好了。

首先,在当前用户的 session 的中查找django_language键;
如未找到,它会找寻一个cookie
还找不到的话,它会在 HTTP 请求头部里查找Accept-Language, 该头部是你的浏览器发送的,并且按优先顺序告诉服务器你的语言偏好。 Django会尝试头部中的每一个语种直到它发现一个可用的翻译。
以上都失败了的话, 就使用全局的 LANGUAGE_CODE 设定值。

3. 汉化到底是zh_Hans还是zh_CN (Django v2.0.9)

我看网上很多教程都是makemessags -l zh_CN,在Django (v2.0.9)中如此操作,发现完全没有生效,这里又是怎么回事呢?

django/middle/locale.py我们可以看出在处理请求时,Django会首先根据【步骤2】中的流程来判断客户端语言,其默认配置文件在django/conf/locale/__init__.py中,我们可以看到,zh_Hanszh-cn以及其他简体中文的fallback项,也就是说如果客户端请求了zh-cn语言,服务器是按照zh-Hans语言返回的,也就是根据这个值——zh-HansLOCALE_PAHTS加载.mo文件完成多语言的。这也就是为什么makemessages -l zh_CN不生效的原因。

那么如何让在zh_CN目录下的翻译生效呢,很简单,配置LANGUAGES,添加zh-cn即可,这样Django就可以直接根据zh-cn来加载zh_CN目录下的.mo了,不过多数情况下并没有这种必要,除非同时提供了多种简体中文语言,并且各地区有差别。

1
2
3
LANGUAGES += [
('zh-cn', gettext_noop('Simplified Chinese')),
]

参考

  1. 第十九章: 国际化
  2. How Django discovers language preference
  3. https://docs.djangoproject.com/en/2.1/topics/i18n/translation/#how-django-discovers-language-preference