Django国际化-铲坑!!!

Django国际化

  • Django国际化-铲坑!!!
    • 使用环境:Django1.11, python3.6
    • 一、 开启国际化的支持,需要在settings.py文件中设置如下
    • 二、指定待翻译字符串
      • 1. 标准翻译
      • 2. 复数
    • 三、生成需要翻译的文件(.po)
    • 四、编译语言文件
    • 五、Django如何发现语言偏好
    • 六、Django如何发现翻译

Django国际化-铲坑!!!

使用环境:Django1.11, python3.6

对于Django国际化首先要看官方文档,然后参考admin中国际化的设计,再结合本文档即可大事告成!
Django admin位置python3.6/site-packages/django/contrib/admin/locale

一、 开启国际化的支持,需要在settings.py文件中设置如下

 MIDDLEWARE_CLASSES = (
    ...
    'django.middleware.locale.LocaleMiddleware',    # 请注意注意, 需要放在'django.contrib.sessions.middleware.SessionMiddleware'和 'CacheMiddleware' 的后面。
    )
    LANGUAGE_CODE = 'zh-Hans'  # 要问Django语言有哪些,请到这个目录下面找(python/site-packages/django/conf/locale/)
    TIME_ZONE = 'UTC'
    USE_I18N = True
    USE_L10N = True
    USE_TZ = True
     
    LANGUAGES = (                # 系统支持的语言种类,Django LocaleMiddleware 根据请求信息会自动选择
        ('en', ('English')),
        ('zh-Hans',_('中文简体')),
        ('zh-Hant',_('中文繁體')),
    )
    #翻译文件所在目录,需要手工创建
    LOCALE_PATHS = (
        os.path.join(BASE_DIR, 'locale'),
    )

二、指定待翻译字符串

这里主要简绍 标准翻译 复数,在Python 代码中

1. 标准翻译

  1. 使用函数 ugettext() 来指定一个翻译字符串。 作为惯例,使用短别名 _ 来引入这个函数以节省键入时间.
    在下面这个例子中,文本 “Welcome to my site” 被标记为待翻译字符串:
from django.utils.translation import ugettext as _

def my_view(request):
    output = _("Welcome to my site.")
    return HttpResponse(output)
def my_view(request, m, d):
    output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}
    return HttpResponse(output)

在生成翻译的文件.po文件中将出现:(生成方法详见–> 三、生成需要翻译的文件(.po)

#: hello/views.py:10
msgid "Welcome to my site."
msgstr "欢迎访问"

#: hello/views.py:36
#, python-format
msgid "Today is %(month)d"
msgstr "今天是 %(month)d 月"

2. 复数

函数django.utils.translation.ungettext() 用于指定多元化的消息。
ungettext 接收三个参数:单数形式的翻译字符串、复数形式的翻译字符串和对象的个数。
这个函数用于当你的Django 应用所要本地化的语言中,复数形式 比英语中的要复杂时(‘object’ 表示单数,‘objects’ 表示所有count 不等于一的情形,无论具体的值是多少)。

from django.utils.translation import ungettext
from django.http import HttpResponse

def hello_world(request, count):
    page = ungettext(
        'there is %(count)d object',
        'there are %(count)d objects',
    count) % {
        'count': count,
    }
    return HttpResponse(page)

这个例子中对象的数字作为count变量传递给翻译语言
注意: 在使用 ungettext()的时候, 确保你你使用在每一个占位符中使用同一个名称。 在上面的例子中, 你可以注意到我们是怎么在两种翻译中使用count这个变量的。
在生成翻译的文件.po文件中将出现:(生成方法详见–> 三、生成需要翻译的文件(.po)

#: hello/views.py:59
#, python-format
msgid "There is %(count)d  object available."
msgid_plural "There are %(count)d  objects available."
msgstr[0] "(单个)这是 %(count)d 对象 "
msgstr[1] "(多个)这是 %(count)d 对象"

三、生成需要翻译的文件(.po)

  1. manage.py同级目录下完成

    • 首先在manage.py同级目录下新建 locale 文件夹,然后运行下面命令生成相应语言包
    • python manage.py makemessages -l zh_Hans
      python manage.py makemessages -l zh_Hant
    • 注意:如果翻译不生效,请检查你的语言包的文件夹是不是有 中划线,请用下划线代替它。
      比如 zh-Hans 改成 zh_Hans (但是要注意 setttings.py 中要用 中划线,不要也改了
      Django国际化-铲坑!!!_第1张图片
  2. 每个.po文件首先包含一小部分元数据,例如翻译维护者的联系信息,但文件的大部分是翻译对照:被翻译字符串和特定语言的实际翻译文本之间的简单映射。
    例如,有一个像下面这样的待翻译字符串:
    _(“Welcome to my site.”)
    在.po文件中将包含一条下面样子的条目:

    #: path/to/python/module.py:23 
    msgid "Welcome to my site." 
    msgstr "" 
    

    这三行内容各自代表下面的意思:

     第一行通过注释表达该条要翻译的字符串在视图或模版中的位置;
     msgid:要翻译的字符串。不要修改它。
     msgstr:翻译后的文本。一开始它是空的,需要翻译人员逐条填写。 
     这是一个文本文件,需要专业的翻译人员将所有的msgstr空白‘填写’齐全。如果你的项目比较大,这可能是个磨人的事。
    

四、编译语言文件

# 运行下面命令,Django将自动搜索所有的.po文件,将它们都翻译成.mo文件。
django-admin compilemessages

Django国际化-铲坑!!!_第2张图片

五、Django如何发现语言偏好

一旦你准备好翻译,或者你只是想使用Django 自带的翻译,你需要为你的应用启用翻译。
在这些功能背后,Django拥有一个灵活的模型来确定在安装和使用应用程序的过程中选择使用的语言。
要设定一个安装阶段的语种偏好,请设定LANGUAGE_CODE。如果其他翻译器没有找到一个译文,Django将使用这个语种作为缺省的翻译最终尝试。
如果你想要的是用你的母语运行Django,你只需设置LANGUAGE_CODE并确保相应的message files及其编译版本(.mo)。
如果你想让每个用户指定首选语言,那么你还要 使用 LocaleMiddleware. LocaleMiddleware 会打开基于请求数据的语言选择。 它为每个人用户的内容进行个性化。
要使用LocaleMiddleware,请将’django.middleware.locale.LocaleMiddleware’添加到您的MIDDLEWARE设置中。 因为中间件顺序很重要,请遵循以下准则:

  • 确保它是安装的第一个中间件之一。
  • 因为 LocalMiddleware 要用到session数据,所以需要放在 SessionMiddleware 之后。
  • 如果使用LocaleMiddleware,请在其后放置CacheMiddleware。

例如,您的MIDDLEWARE可能如下所示:

MIDDLEWARE = [
   'django.contrib.sessions.middleware.SessionMiddleware',
   'django.middleware.locale.LocaleMiddleware',
   'django.middleware.common.CommonMiddleware',
]

LocaleMiddleware尝试通过以下算法确定用户的语言首选项:

  • 首先,它在请求的URL中查找语言前缀。 这仅在您在根URLconf中使用i18n_patterns函数时才会执行。 有关语言前缀以及如何将网址格式国际化的详细信息,请参见Internationalization: in URL patterns中。
  • 否则,它会在当前用户的会话中查找LANGUAGE_SESSION_KEY键。
  • 如果没有,它寻找一个cookie。所使用的Cookie名称由LANGUAGE_COOKIE_NAME设置设置。 (默认名称为django_language。)
  • 如果没有,它会查看Accept-Language HTTP标头(Accept-Language: zh-CN)。 此标题由您的浏览器发送,并按优先级顺序告诉服务器您喜欢哪种语言。 Django尝试标题中的每种语言,直到找到一个可用的翻译。
  • 否则,它使用全局LANGUAGE_CODE设置。

笔记:

  • 在每个位置,语言首选项应为标准language format,作为字符串。 例如,巴西葡萄牙语是pt-br。
  • 如果基本语言可用,但指定的子语言不是,Django使用基本语言。 例如,如果用户指定de(奥地利德语),但Django只有de-at可用,则Django使用de。
  • 只能选择LANGUAGES设置中列出的语言。 如果要将语言选择限制为所提供语言的一个子集(因为您的应用程序不提供所有这些语言),请将LANGUAGES设置为语言列表。 像这样:
    LANGUAGES = [
    	  ('de', _('German')),
    	  ('en', _('English')),
    	]
    

此示例将可用于自动选择的语言限制为德语和英语(以及任何子语言,如de-ch或en-us)。

  • 如果您定义自定义LANGUAGES设置(如上一个项目符号所述),则可以将语言名称标记为翻译字符串 - 但使用ugettext_lazy()而不是ugettext()以避免循环导入
    下面是一个示例设置文件:
    from django.utils.translation import ugettext_lazy as _
    
    LANGUAGES = [
        ('de', _('German')),
        ('en', _('English')),
    ]
    

一旦LocaleMiddleware确定用户的首选项,它使每个HttpRequest的此首选项可用作request.LANGUAGE_CODE。 随意在您的视图代码中读取此值。 这里有一个简单的例子:

from django.http import HttpResponse

def hello_world(request, count):
    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中。

六、Django如何发现翻译

在运行时,Django构建一个内存中的文字 - 翻译目录。 为了实现这一点,它通过遵循该算法关于其检查不同文件路径以加载编译的message files(.mo)和优先级的顺序来寻找翻译多个翻译为同一个字面量:

  1. LOCALE_PATHS中列出的目录具有最高优先级,首先出现的优先级高于稍后出现的优先级。
  2. 然后,它会查找并使用INSTALLED_APPS中列出的每个已安装应用程序中是否存在locale目录。 首先出现的优先级高于稍后出现的优先级。
  3. 最后,在django/conf/locale中提供的Django提供的基本翻译用作后备。

在所有情况下,包含翻译的目录的名称应使用locale name符号命名。 例如。 pt_BR,de,es_AR等。

这样,您可以编写包含自己的翻译的应用程序,并且可以覆盖项目中的基本翻译。 或者,您可以从几个应用程序构建一个大项目,并将所有翻译成一个大的通用消息文件,特定于您正在撰写的项目。 这是你的选择。

所有消息文件存储库的结构都是相同的。 他们是:

  • 搜索设置文件中LOCALE_PATHS中列出的所有路径 / LC_MESSAGES / django的。(PO | MO)
  • $ APPPATH /区域/ / LC_MESSAGES / django的。(PO | MO)
  • $ PYTHONPATH / django的/ CONF /区域/ / LC_MESSAGES / django的。(PO | MO)

要创建邮件文件,请使用django-admin makemessages工具。 And you use django-admin compilemessages to produce the binary .mo files that are used by gettext.

您还可以运行django-admin compilemessages --settings=path.to.settings您的LOCALE_PATHS设置中的所有目录。

你可能感兴趣的:(Django)