Django分析之国际化处理
最近在公司终于开始做web开发了,本以为会是简单的首页之类的小规模项目,结果上来就是一个处理大数据分析的项目,一个关于油品分析的系统,不过我接到的第一个任务是做这个网站的国际化处理,虽然项目还没有上线,还差的很多,但是国际化这个东西使用的是Django自带的来处理的,所以在一边写项目的时候就要写好国际化的代码,所以我现在就开始处理我的国际化了.
大家可以在Django Doctment上看官方的说明,我在这里就不复制官方文档了,django框架带有完善的I18N和L10N支持,其实现是基于GNU gettext的。最近看着文档研究了一下,在这里概要总结一下django国际化的处理流程。
经典用法是把ugettext_lazy导为_使用,该函数标记要翻译的符号,并在要输出该符号的时候进行翻译,返回unicode对象:
1 from django.utils.translation import ugettext as _ 2 from django.utils.translation import ugettext_lazy 3 4 label=ugettext_lazy(u"日期") 5 ...... 6 opt = {"data": [], "name": _(u'销售额({first},{last})')
需要输出label和opt的地方就会自动转成对应的国际化语言了,现在是在代码里面改好了,那么接下来该怎么使用呢?
紧接着在对应app目录创建locale目录,并按此格式<language>/LC_MESSAGES/创建好欲支持的语言目录,转到app目录下执行django-admin.py makemessages --all 命令, 把所有标记的翻译符号导出为po文件,打开各个<language>/LC_MESSAGES/django.po文件,把符号翻译为对应的本地言语,再执行django-admin.py compilemessages把po文件编译为mo文件,这两个命令一定要在locale的当前目录执行。
那么接下来,就要在settings文件中配置关于国际化的设置了,我们需要在settings文件中这样配置:
1 USE_I18N = True 2 3 USE_L10N = True 4 5 LANGUAGE_CODE = 'zh-cn' 6 7 TIME_ZONE = 'Asia/Shanghai' 8 9 LANGUAGES = ( 10 ('en', ugettext_lazy(u"英文")), 11 ('zh-cn',ugettext_lazy(u"中文")), 12 ) 13 14 #是否自动判断Accept-Language头转换语言 15 LOCALEURL_USE_ACCEPT_LANGUAGE=False 16 17 #是否显示语言前缀 18 PREFIX_DEFAULT_LOCALE = True 19 20 #是否在session中保存用户指定的语言 21 LOCALEURL_USE_SESSION=True 22 23 MIDDLEWARE_CLASSES = ( 24 'django.middleware.gzip.GZipMiddleware', 25 'django.middleware.common.CommonMiddleware', 26 'django.contrib.sessions.middleware.SessionMiddleware', 27 'django.middleware.locale.LocaleMiddleware', 28 'django.middleware.csrf.CsrfViewMiddleware', 29 'django.contrib.auth.middleware.AuthenticationMiddleware', 30 'django.contrib.messages.middleware.MessageMiddleware', 31 ) 32 33 TEMPLATE_CONTEXT_PROCESSORS = ("django.contrib.auth.context_processors.auth",
"django.core.context_processors.debug",
"django.core.context_processors.i18n",
"django.core.context_processors.media",
"django.core.context_processors.static",
"django.core.context_processors.tz",
"django.contrib.messages.context_processors.messages")
注意:MIDDLEWARE_CLASSES中要增加'django.middleware.locale.LocaleMiddleware',该中间见要出现在SessionMiddleware和CacheMiddleware后,其他所有中间件之前,而TEMPLATE_CONTEXT_PROCESSORS 中要增加 'django.core.context_processors.i18n'.
当你做完以上这些操作你就可以让你的项目成功的显示多语言了,那接下来呢?你会发现实际上项目中还会有一些是无法翻译过来的,那是为什么呢?因为他们都是通过外部的js来渲染进模板中的,这样的话你再使用上面提到的方法就不行了,那么该怎么办呢?下面我就来介绍如何在外部js中做多语言的翻译.
首先,我们要在urls.py文件中这样配置:
url(r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
然后在需要国际化的模板页中引入:
<script type="text/javascript" src="/jsi18n/userauth"></script>
那么,在这个页面中可以用javascript调用gettext方法实现国际化。/userauth是locale文件所在的路径(可以是app路径,此app应该在settings.py的INSTALL_APP中配置好)。接着,在userauth的locale路径下,如/zh_CN路径下新建djangojs.po文件,将msgid和msgstr的对应关系写入。再利用django-admin.py compilemessages即可以在javascript中利用gettext('bug.manage')获得它对应的国际化值。
对于Djangojs.py文件的建立我们采用这样的命令:
django-admin.py makemessage -d djangojs -l en
这样,就会在之前我们生成django.py文件的目录里产生一个djangojs.py文件了,这样就可以直接进行翻译了.而对于js文件中的字符串我们采用什么样的方式呢?
var name = String.format("xxxxxx{0}",gettext('xxx'))
到此为止就基本不会再出现什么问题了,那么Django是按照什么样的顺序来确定应该是使用什么样的语言呢?
1,在用户session里查找django_language key
2,如果不存在session,查找django_language cookie
3,查找http头 Accept-Language
4,以后都未设置,使用settings.LANGUAGE_CODE
决定了使用哪种语言后,按如下找顺序查找mo文件:
1,settings LOCALE_PATHS变量指定的路径
2,每个app目录下的locale目录
3,工程目录下的locale目录
4,最后是django/conf/locale目录
当有重复的mo文件时,mo优先级同查找顺序一致,即先找到的会屏蔽其后边的mo项
OK!!基本上关于Django多语言处理的地方都介绍过了,这样就成功的实现了多语言的处理了~~~