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多语言处理的地方都介绍过了,这样就成功的实现了多语言的处理了~~~

 

posted @ 2014-12-05 16:53  F-happy  阅读(6007)  评论(1编辑  收藏  举报