当我们在构建具有国际化性的web站点时,通常需要满足在不同的国家或地区显示本地的语言。而django提供了强大的翻译机制,并且只需要很少的代码即可完成国际化的需要。django的配置文件settings.py中,默认是开启国际化支持的,USE_I18=True,如果您的站点不需要国际化,那么可以设置USE_I18N=False,这样对于您的站点来说,就不需要加载国际化支持的机制。另外对于django的模板也同样有国际化的支持,如果您不需要,可以将TEMPLATE_CONTEXT_PROCESSORS中的"django.core.context_processors.i18n"去掉。
在python代码中,需要对要翻译的文字进行标记,标记的方法是使用"_"方法。其实是django.utils.translation.gettext方法,类似的方法还有django.utils.translation.gettext,django.utils.translation.gettext_lazy和django.utils.translation.ugettext_lazy方法。通常使用“_”来代替这些名称较长的方法,如“django.utils.translation.ugettext_lazy as _”。以上方法带“u”的表示unicode编码,另外gettext(或ugettext)与gettext_lazy(或ugettext_lazy)有些差异,gettext_lazy使得其值只有在访问时才会被翻译,而不是gettext_lazy调用时翻译。
在编写python代码时,可以这样来标记要翻译的文字,如下model的定义:
- from django.utils.translation import ugettext_lazy as _
- from django.db import models
- class DemoModel(models.Model):
- demofield = models.CharField(_(u'demo field'), help_text = _(u'Help text'), max_length = 10)
或者view的定义:
- def index(request):
- return HttpResponse(_(u'Welcome to my site.'))
在定义django的模板时,django也提供了国际化的接口,您需要在模板中添加“{% load i18n %}”,然后就可以使用trans标记了,如:
- {% trans "This is my site" %}
如果你只想标记字符串而想以后再翻译,可以添加noop选项:
- {% trans "This is my site" noop %}
但是trans标记只能翻译字符串,不能使用变量,如果有变量需要翻译,那么需要使用{% blocktrans %}标记。使用方法如下:
- {% blocktrans %}This is my site {{ site_name }}{% endblocktrans %}
另外RequestContext对象有三个针对翻译的变量LANGUAGES,LANGUAGE_CODE和LANGUAGE_BIDI,分别表示语言列表,当前用户语言的偏好,和语言的书写方式:
- LANGUAGES 是一系列元组组成的列表,每个元组的第一个元素是语言代码,第二个元素是用该语言表示的语言名称。
- LANGUAGE_CODE是以字符串表示的当前用户偏好语言(例如, en-us )。(详见 Django 如何确定语言偏好。)
- LANGUAGE_BIDI是当前语言的书写方式。若设为 True,则该语言书写方向为从右到左(如希伯来语和阿拉伯语);若设为 False,则该语言书写方向为从左到右(如英语、法语和德语)。
当然如果想要在模板中使用这三个变量就需要在view中添加该对象。如view的返回值:
- return render_to_response('app/index', RequestContext(request, {'site_name':'My site name'}))
其实还有另一种方式,也能达到在模板中使用上面三个变量的目的,如下代码:
- {% load i18n %}
- {% get_current_language as LANGUAGE_CODE %}
- {% get_available_languages as LANGUAGES %}
- {% get_current_language_bidi as LANGUAGE_BIDI %}
上面介绍了如何进行翻译及其国际化相关的内容,但django默认情况下时根据客户端语言的使用偏好来对内容进行翻译的,但是当我们安装的是英文操作系统希望现在中文界面时,或者中文操作系统显示英文界面时,就需要手动的设置了。实现手动设置语言偏好需要我们在web界面中添加一个语言选择的下拉框。如下,采用自定义tag的方式定义该下拉框,在templatetags目录下添加langs.py文件,内容如下:
- # -*- coding:utf-8 -*-
- from django import template
- from django.utils.translation import get_language_info
- from django.conf import settings
- LANGUAGES = []
- for lang_code in settings.LANGUAGES_SUPPORTED:
- LANGUAGES.append(get_language_info(lang_code))
- register = template.Library()
- @register.inclusion_tag('app/parts/languages_select_part.html')
- def language_select(default):
- return {'languages':LANGUAGES, 'default':default}
方法language_select接收一个参数,该参数表示当前使用的语言代码,我们将支持的语言配置在settings.LANGUAGES_SUPPORTED下,我们只支持英文和中文。值为:
- LANGUAGES_SUPPORTED = ('en', 'zh-cn',)
“app/parts/languages_select_part.html”模板的定义如下:
- {% if languages %}
- <form id="language-select-form" method="post" action="{% url django.views.i18n.set_language %}">{% csrf_token %}
- <select class="dropdown" onchange="this.form.submit();" name="language">
- {% for lang in languages %}<option value="{{ lang.code }}" {% if lang.code == default %}selected="selected"{% endif %}>{{ lang.name_local }}</option>
- {% endfor %}</select>
- </form>{% endif %}
模板中action的值,设置为“{% url django.views.i18n.set_language %}”,这是django提高的设置语言的接口。我们需要在urls.py中添加一段代码:
- urlpatterns += patterns('',
- url(r'^setlang/$', 'django.views.i18n.set_language', name = 'setlang'),
- )
那么在网站的模板中,就可以通过如下代码将该下拉框添加到页面中:
- {% load langs %}
- {% language_select LANGUAGE_CODE %}
当选择语言后,页面会自动刷新,并且根据选择的语言进行翻译。如果您的站点还没有翻译,可以查看admin的界面显示。