Django实现国际化的步骤

有些话、适合烂在心里 提交于 2020-04-07 11:01:09

Django国际化的详细文档: http://djangobook.py3k.cn/2.0/chapter19/ (中文) 英文好的可以看: https://docs.djangoproject.com/en/1.4/topics/i18n/

在这里写下Django实现国际化的基本步骤,详细内容见如上链接;

(只讲步骤,不谈原理;因为我讲不清,原理在上面链接中讲的很清楚;)

静态翻译html

一.)使用Django模板引擎的解析实现国际化,说白了就是 {% trans %}标签国际化

1.)将 {% load i18n %} 放在模板最前面;在html(默认的格式), txt, xml等Django模板支持的文件中将需要国际化的字段用 {% trans '****'%}表示;

2.)在Django项目根目录新建一个locale目录,然后在项目根目录下执行django-admin.py makemessages -l zh_CN (最后一个字段是语言代码;如果需要翻译的模板不是html,则需要通过参数-e 指明, 如: django-admin.py makemessages -l de -e txt),为每个要支持的语言执行一次; 该命令将生成对应语言的po文件,如locale/zh_CN/LC_MESSAGES/django.po。

3.)在每个po文件中,为所有需要翻译的字段填写对应语言的翻译内容; 每个msgstr对应上面的msgid;翻译完后将po文件保存为'UTF-8 无BOM'格式;

4.)执行django-admin.py compilemessages将所有的po文件转成便于编译模块处理的*.mo文件;

5.)在settings里面修改LANGUAGE_CODE查看效果;

静态翻译外部js

二.)外部javascript的国际化

1.)在js文件中将需要国际化的字段用 gettext('***')代替;

2.)在项目根目录下创建一个三级目录, 如: transjs/jsi18n/locale;在transjs和jsi18n下都放入__init__.py文件,保证改目录能够被导入;将要被国际化的js文件拷贝到jsi18n下;

3.)将transjs/jsi18n安装到INSTALL_APPS下;

4.)在html中,在导入需要翻译的js前,添加<script type='text/javascript' src='/jsi18n'></script>;

5.)在全局的urls.py中添加如下代码

js_info_dict = {

'packages': ('transjs.jsi18n',),

}

urlpatterns += patterns('',

(r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),

)

6.)在trans/jsi18n下执行django-admin.py makemessages -d djangojs -l de,生成po文件,在po文件中填入相应语言的翻译内容;

7.)在trans/jsi18n下执行django-admin.py compilemessages编译po文件,生成mo文件;

8.)在settings里面修改LANGUAGE_CODE查看效果;

以上是静态翻译的基本步骤,是根据settings.py中的LANGUAGE_CODE翻译的,下面看看如何动态翻译

三.)动态翻译(提供语言列表让用户选择,根据用户选择的语言动态切换),以下步骤是在完成了上面一,二的基础上进行的;

1.)在settings.py中设置所支持的语言列表; 如支持中文和英文

LANGUAGES = (

('zh', '简体中文'),

('en', 'English'),

)

2.)添加中间件LocaleMiddleware, 在MIDDLEWARE_CLASSES设置中增加 'django.middleware.locale.LocaleMiddleware';必须放在 SessionMiddleware和CacheMiddleware的后面;

3.)重定向视图,Django自带了一个 django.views.i18n.set_language 视图,作用是设置用户语言偏好并重定向返回到指定的页面;

在URLconf中加入下面这行代码来激活这个视图:

(r'^i18n/', include('django.conf.urls.i18n')),

4.)提交切换语言的请求,下面是一个请求的表单例子;在next的value中指定切换语言后显示的页面;

<form action='/i18n/setlang/' method='post'>

<input name='next' type='hidden' value='/next/page/' />

<select name='language'>

{% for lang in LANGUAGES %}

<option value='{{ lang.0 }}'>{{ lang.1 }}</option>

{% endfor %}

</select>

<input type='submit' value='Go' />

</form>

四.)翻译的内容中含有参数的情况

1.)在html中使用模板参数,此时必须使用{% blocktrans %}代替{% trans %},例如:

{% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}

其中{{ value }}是一个django模板变量,由django在将模板转换成具体的html时传入;

2.)如果要使用模板过滤器来翻译一个模板表达式,需要在翻译的这段文本中将表达式绑定到一个本地变量中:

{% blocktrans with value|filter as myvar %} This will have {{ myvar }} inside. {% endblocktrans %}

myvar就是用来绑定表达式本地变量;filter是django所支持的所有过滤器,下面是个使用length的例子;

例如:有一个模板变量{{ funcname }},在翻译串内需要用到该变量的字符长度:

{% blocktrans with funcname|length as len %}

There is {{ len }} letter in {{ funcname }}.

{% endblocktrans %}

len :本地变量,用来绑定(或者说保存){{funcname}}的长度,然后在作为参数出现在翻译字符串内;

{{ funcname }}: 就是1.)里面所讲的模板变量;

这里又引出了另一个问题,就是如果len大于1怎么办? Good question,its answer is using {% plural %} tag. 简单的说就是把单复数形式的句子都写一遍,用{% plural %}区分开,先写单数形式,再写复数形式,实际翻译时,会自动根据len的值来选择句子,具体如下:

{% blocktrans with funcname|length as len %}

There is only one letter in {{funcname}}.

{% plural %}

There are {{ len }} letters in {{ funcname }}.

{% endblocktrans %}

3.)js中使用参数;这个也许有更精妙的方法,但是目前我只知道下面的方法;

在需要翻译的字符串里放入一个占位符,然后在得到翻译的字串后,将占位符用实际的值取代;

如; gettext('Nice to meet you, %s');

这个地方用 %s 作为占位符;在得到翻译的字串后,将 %s 替换成实际的人名即可;

<完>


原理分析:

django.middleware.locale.LocaleMiddleware

LocaleMiddleware 按照如下算法确定用户的语言:

  • 1. 首先,在当前用户的 session 的中查找django_language(LANGUAGE_SESSION_KEY = '_language')键;

  • 2. 如未找到,它会找寻一个cookie,key为LANGUAGE_COOKIE_NAME = 'django_language'

  • 3. 还找不到的话,它会在 HTTP 请求头部里查找Accept-Language, 该头部是你的浏览器发送的,并且按优先顺序告诉服务器你的语言偏好。 Django会尝试头部中的每一个语种直到它发现一个可用的翻译。

  • 4. 以上都失败了的话, 就使用全局的 LANGUAGE_CODE 设定值。


  • 只有在 LANGUAGES 设置中列出的语言才能被选用。 若希望将语言限制为所提供语言中的某些(因为应用程序并不提供所有语言的表示),则将 LANGUAGES 设置为所希望提供语言的列表,例如: 例如:


  • LANGUAGES = (
      ('de', _('German')),
      ('en', _('English')),
    )

一旦LocaleMiddleware决定用户的偏好,它会让这个偏好作为request.LANGUAGE_CODE对每一个HttpRequest有效。请随意在你的视图代码中读一读这个值。 以下是一个简单的例子:

def hello_world(request):
    if request.LANGUAGE_CODE == 'de-at':
        return HttpResponse("You prefer to read Austrian German.")
    else:
        return HttpResponse("You prefer to read another language.")

注意,对于静态翻译(无中间件)而言,此语言在settings.LANGUAGE_CODE中,而对于动态翻译(中间件),它在request.LANGUAGE_CODE中。


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!