前言

一个大型网站的构建中,国际化是一个不可或缺的部分,它可以提供对不同语言、时区的支持。

  • 国际化:是指为了该软件在任何地区的潜在使用而进行程序设计的过程。 它包括了为将来翻译而标记的文本(比如用户界面要素和错误信息等)、日期和时间的抽象显示以便保证不同地区的标准得到遵循、为不同时区提供支持,并且一般确保代码中不会存在关于使用者所在地区的假设。 您会经常看到国际化被缩写为“I18N”(18表示Internationlization这个单词首字母I和结尾字母N之间的字母有18个)。
  • 本地化:是指使一个国际化的程序为了在某个特定地区使用而进行实际翻译的过程。 有时,本地化缩写为 L10N(localization) 。

我们这里讲本地化,对于一个前后端分离的项目结构,如Django+React,那么前端可以使用react-intl模块处理编辑页面中显示的语言内容。但是,在前后端的交互过程中,如前端请求失败,后端返回错误信息,那么这个错误信息前端是无法动态翻译的,此时一种可行的方法是我们就需要在后端将要返回的内容进行翻译,返回给前端显示。

Django中的翻译

Django本身是完全国际化了的,所有的字符串均因翻译所需而被标记,您只需要添加少量的挂接代码到您的Python代码和模板中。 这些挂接代码被称为“翻译字符串”。它们告诉Django:如果这段文本的译文可用的话,它应被翻译为终端用户指定的语言。对Django应用只需进行三步:

  1. 指定翻译字符串
  2. 创建语言文件
  3. 配置

指定翻译字符串

  • 标准翻译,使用函数 ugettext() 来指定一个翻译字符串。 作为惯例,使用短别名 _ 来引入这个函数以节省键入时间.

    1
    2
    3
    4
    5
    from django.utils.translation import ugettext as _
    def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)
  • 惰性翻译,使用gettext_lazy() 函数,使得其中的值只有在访问时才会被翻译,而不是在 gettext_lazy() 被调用时翻译。

    1
    2
    3
    4
    from django.utils.translation import ugettext_lazy
    class MyThing(models.Model):
    name = models.CharField(help_text=ugettext_lazy('This is the help text'))

创建语言文件

当你标记了翻译字符串,你就需要写出(或获取已有的)对应的语言翻译信息。为一种语言创建一个信息文件,信息文件以 .po 为后缀名。

  • 创建信息文件
    使用Django工具manage.py,运行命令:
    1
    django-admin.py makemessages -l zh_CN -e py

zh_CN是所创建信息文件的语言代码,配置文件中配置的是zh-cn,但是使用zn-cn是无效的文件夹名,所以我们使用zh_CN保存语言文件。
-e 选项指定文件扩展名来检测。
-a 会检验所有的文件名和模板检测。
这段脚本遍历你的项目源树或你的应用程序源树并且提取出所有为翻译而被标记的字符串。 它在 locale/LANG/LC_MESSAGES 目录下创建(或更新)了一个信息文件。针对上面的zh_CN,应该是locale/zh_CN/LC_MESSAGES/django.po。

  • 编译信息文件
    创建信息文件之后,每次对其做了修改,都需要将它重新编译成一种更有效率的形式,供 gettext 使用。可以使用django-admin.py compilemessages完成。这个工具作用于所有有效的 .po 文件,创建优化过的二进制 .mo 文件供 gettext 使用。
    1
    django-admin.py compilemessages

配置

总结

我们这里只是简单的总结了Django中翻译的一般用法,其中还有许多细节,包括 gettext() 的字符串可以接受占位符、在模板中使用翻译等等细节,使用中可以继续深入了解