最近在项目里需要用到国际化,在网上找了很多方法,现在做个总结。
Django框架天然支持国际化,只要在settions.py 文件中设置国际化相关配置就可以使用这个功能了。
下面是与国际化相关的配置信息(不相关的没贴出来)
# 中间件设置
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware', # 这个是国际化功能的中间件,一定要加在SessionMiddleware和CommonMiddleware中间
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
# 上下文设置
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'django.template.context_processors.i18n', # 一定要加这句
],
},
},
]
# 语言设置
LANGUAGE_CODE = 'en' # 默认语言
TIME_ZONE = 'UTC' # 默认时区
USE_I18N = True # django国际化 True 打开
USE_L10N = True # django本地化 True 打开
USE_TZ = True # 自动时区
# 设置国际化要用到的语言,具体支持的语言的代码可以到C:\Program Files\Python\Python3\Lib\site-packages\django\contrib\sites\locale 下查看
LANGUAGES = (
('en', 'English'),
('es', 'Spanish'),
('pt', '葡萄牙'),
('ja', '日语'),
('ko', '韩国'),
)
# 翻译文件所在目录,需要手工创建locale文件夹,一般与manage.py同级
LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale'),
)
在windows上使用django的功能,需要安装配置gettext,点击这里下载。
安装:直接安装就可以了,安装完找到安装的目录。
配置:我安装到C:\Program Files\gettext-iconv下了,然后打开控制面板>系统>高级>环境变量,在系统变量的Path添加一条C:\Program Files\gettext-iconv\bin
结果如图:
到这里环境基本配置好了。
标记要国际化的字符串
1.在.py文件中
django.utils.translation.ugettext() #指定一个翻译字符串,一般都用于 views.py
django.utils.translation.gettext_noop() #标记一个不需要立即翻译的字符串。 这个串会稍后从变量翻译。使用这种方法的环境是,有字符串必须以原始语言的形式存储(如储存在数据库中的字符串)而在最后需要被 翻译出来(如显示给用户时)。
django.utils.translation.gettext_lazy() #ugettext_lazy() 将字符串作为惰性参照存储,而不是实际翻译 , 一般会用于 models.py。 翻译工作将在字符串在字符串上下文中被用到时进行,比如在 Django 管理页面提交模板时。在 Django 模型中总是无一例外的使用惰性翻译
django.utils.translation.ungettext() #函数包括三个参数: 单数形式的翻译字符串,复数形式的翻译字符串,和对象的个数(将以 count 变量传递给需要翻译的语言)。
这里强烈要求使用惰性翻译,这样能够有效节省django的性能开支。以下我们以惰性翻译为例举个例子:
from django.utils.translation import gettext_lazy as _
transText = _("please login")
2.在模板中
在模板开头必须要加{% load i18n %},加这个标签才能使用国际化标记标签
国际化标记标签有两种:
- {% trans "string" %} # 这个标签会将"string"这个字符串在页面显示成.po文件中翻译的,下面会讲.po文件的生成
- {% blocktrans%}{%endblocktrans %} # 这个标签一般用在带有变量的字符串上,
{% blocktrans%}{%endblocktrans %}用法 :
{% blocktrans with foo|filter as bar and baz|filter as boo %}
This is {{ bar }} and {{ boo }}.
{% endblocktrans %}
还可以用复数:
{% blocktrans count var|length as count %}
There is {{ count }} object.
{% plural %}
There are {{ count }} objects.
{% endblocktrans %}
制作翻译文件(.po文件)
制作翻译文件首先要安装配置gettext,前文已经讲过安装方法了
在locale同级目录执行命令:django-admin makemessages -l es
-l后的参数是前面讲的配置settings.py中的LANGUAGES写的语言代码。
也可以使用命令django-admin makemessages --all 生成全部的,但是在windows中只能一个一个生成,要使用上面那条命令
执行成功会在locale文件夹下生成对应的翻译文件
django.po文件里存的是要翻译的字符串和翻译后的字符串,举个例子:
msgid "Language" # 要翻译的字符串
msgstr "Idioma" # 翻译后的字符串
django在识别出用户使用的语言后会自动将原本在模板中的{% trans 'Language' %} 解析成 Idioma
编译.po文件
在locale同级目录执行
django-admin compilemessages
django会自动将locale目录下所有语言的.po文件编译成二进制的.mo文件
在修改.po文件重新编译后要重启django程序,否则页面显示的还是上次翻译的内容
在项目中配置切换语言
首先配置url,在url.py加入一行代码
path('i18n/', include('django.conf.urls.i18n')),
然后在模板中加入下面的代码
<form action="{% url 'set_language' %}" method="post">
{% csrf_token %}
<input name="next" type="hidden" value="{{ redirect_to }}"/>
<select name="language">
{% for language in LANGUAGES %}
<option value="{{ language.0 }}"{% if language.0 == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.1 }}
{% endfor %}
</select>
<input type="submit" value="Go"/>
</form>
django-modeltranslation
但是在实际项目中可能需要被国际化翻译的数据是在数据库中的,这个时候如果再使用.po文件翻译就不太现实了,因为有些数据是不可预知的。所以可以在添加这些数据的时候就添加多种语言版本的。
这里要使用到django-modeltranslation
安装:pip install django-modeltranslation
配置:在settings.py文件中的INSTALLED_APPS添加
modeltranslation这个app
一定要加在 django.contrib.admin 之前,这样就能在数据库迁移的时候自动创建多语言字段,在admin中管理这些字段。
在app内添加translation.py文件,与models.py同级
translation.py:
from modeltranslation.translator import translator, TranslationOptions
from .models import User
class UserTranslationOptions(TranslationOptions):
fields = ('name','desc') # 需要国际化的字段
translator.register(User, UserTranslationOptions)#注册翻译模型
models.py:
from django.db import models
# Create your models here.
class User(models.Model):
name = models.CharField(max_length=20)
desc = models.CharField(max_length=20, null=True)
class Meta:
verbose_name = 'user'
verbose_name_plural = verbose_name
admin.py:
from django.contrib import admin
from .models import User
from modeltranslation.admin import TranslationAdmin
class UserAdmin(TranslationAdmin):
list_display = ['name']
# Register your models here.
admin.site.register(User, UserAdmin)
执行数据库迁移命令,数据库在name,desc字段会添加多个语言的字段
这种方式是将要国际化的内容直接存在数据库,需要的时候会根据用户选择的语言直接从数据库取。
对于静态的数据可以采用django自带的{% trans 'string' %}标签,对于动态的数据使用{% blocktrans%}{%endblocktrans %}加django-modeltranslation模块