Django2.* 国际化

最近在项目里需要用到国际化,在网上找了很多方法,现在做个总结。

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-modeltranslation官方文档

这种方式是将要国际化的内容直接存在数据库,需要的时候会根据用户选择的语言直接从数据库取。

对于静态的数据可以采用django自带的{% trans 'string' %}标签,对于动态的数据使用{% blocktrans%}{%endblocktrans %}加django-modeltranslation模块

posted @ 2019-04-13 21:05  Wuliwawa  阅读(281)  评论(0编辑  收藏  举报