赞
踩
Django 提供了一个强大的国际化和本地化的框架, 以帮助您在多语言和世界各地区进行应用程序的开发:
国际化和本地化的目标是让同一站点为不同的用户提供定制化的语言和格式服务。
Django 完整支持 翻译文本, 格式化日期,时间和数字 以及 时区。
实际上,Django 做了两件事:
它允许开发者和模板作者指定应用的哪个部分应该被翻译或格式化为本地语言,符合本地文化。
它根据用户的配置利用钩子本地化 Web 应用。
翻译依赖于目标语言,而格式化规则依赖于目标国家。此信息由浏览器的 Accept-Language 头提供。但是,时区并不容易获得。
定义
单词国际化(internationalization)和本地化(localization)总是令人迷惑;以下是个简单的定义:
国际化
为本地化准备软件。通常由开发者完成。
本地化
编写翻译和本地格式化。通常由翻译者完成。
为了使 Django 项目可以翻译,你需要在 Python 代码和模板中添加少量钩子。这些钩子被成为 translation strings 。它们告知Django:如果在终端用户语言里,这个文本有对应的翻译,那么应该使用翻译。标记字符串是你的职责,系统只会翻译它知道的字符串。
然后 Django 提供工具将翻译字符串提取到 message file 中。这个文件让翻译者方便地提供翻译字符串。一旦翻译者填写了 message file ,就必须编译它。这个过程依赖 GNU gettext 工具集。
完成后,Django 会根据用户的语言偏好,使用每种可用语言对网页进行即时翻译。
Django 的国际化钩子默认是开启的,这意味着在框架的某些位置存在一些 i18n 相关的开销。如果你不使用国际化,你应该在配置文件里设置 USE_I18N = False 。然后 Django 将进行优化,以免加载国际化机制。
在 Python 代码中进行国际化
使用函数 gettext() 来指定翻译字符串。按照惯例,将其作为下划线( _ )导入,以保存输入。
在这个例子里,文本 “Welcome to my site.” 被标记为翻译字符串:
from django.http import HttpResponse
from django.utils.translation import gettext as _
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)
代码里可以不使用别名。这个例子与上一个例子等同:
from django.http import HttpResponse
from django.utils.translation import gettext
def my_view(request):
output = gettext("Welcome to my site.")
return HttpResponse(output)
翻译适用于计算值。这个例子与前面两个例子等同:
def my_view(request):
words = ['Welcome', 'to', 'my', 'site.']
output = _(' '.join(words))
return HttpResponse(output)
翻译适用于变量。同样,这个例子和上面的等同:
def my_view(request):
sentence = 'Welcome to my site.'
output = _(sentence)
return HttpResponse(output)
本地化:如何创建语言文件
一旦标记了应用程序的字符串文字以供以后翻译,就需要写入(或获取)翻译。这里介绍一下方法。
消息文件
首先需要为新语言创建 message file 文件。消息文件是一个纯文本文件,代表一种语言,它包含所有可用的翻译字段以及如何以给定语言表示。消息文件扩展名是 .po 文件。
Django 附带的工具 django-admin makemessages 会自动创建并保存这些文件。
每个 .po 文件包含少量的元数据(例如翻译维护者的联系方式等等)以及大量的翻译文件 —— 要翻译的字符串以及实际翻译的字段之间的映射。
例如,如果 Djanog 程序包含一段 “Welcome to my site.” 的翻译字符串,像这样:
_("Welcome to my site.")
... 然后 django-admin makemessages 将创建一个包含以下代码片段的 .po 文件 —— 一条消息:
#: path/to/python/module.py:23
msgid "Welcome to my site."
msgstr ""
快速解释:
msgid 是显示在源代码中需要翻译的字符串。不要改动它。
msgstr 是你翻译后的字符串。一开始它是空的,因此你需要填充它。确保在翻译中保留引号。
为了方便,每个消息包含以前缀为 # 且位于 msgid 行上方的注释行的形式的注释行,这个注释行报货文件名和需要翻译字符串的行号。
长消息是特殊的情况。这里,在 msgstr (or msgid) 后的第一个字符串是空字符串。然后内容本身就会在接下来的几行中以每行一串的形式写出来。这些字符串被直接连接起来。不要忘了字符串中尾部的空格,否则,它们会被粘贴在一起而不留空白!
概况
Django 的格式化系统可以在模板中使用指定的格式化工具为当前的 locale 来显示日期、时间和数字。
启用后,访问相同内容的两个用户可能看见不同的日期、时间和数字,这取决于他们本地的语言环境。
格式化系统默认是关闭的。如果要启用它,在配置文件里设置 USE_L10N = True 即可。
使用 localize 参数来使表单字段能本地化输入和输出数据:
class CashRegisterForm(forms.Form):
product = forms.CharField()
revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
在模板中控制本地化
使用 USE_L10N 启用格式化后,每当 Django 在模板中输入数值时,它会试着使用本地语言环境指定的格式化。
然而,使用本地化值可能并不总是合适的——比如,如果你正在输出机器可读的 JavaScript 或 XML ,则始终需要非本地化的值。你也可以在已选的模板里使用本地化,而不是在所有地方使用。
为了更好的控制本地化的使用,Django 提供 l10n 模板库,它包含以下的 tags 和 filters。
模板标签
localize
在模板里启用和禁用模板变量本地化。
相比 USE_L10N ,这个标签可对本地化进行更精细的控制。
要为模板块激活或禁用本地化,请用:
{% load l10n %}
{% localize on %}
{{ value }}
{% endlocalize %}
{% localize off %}
{{ value }}
{% endlocalize %}
概况
当启用了时区支持,Django 在数据库里以 UTC 存储日期信息,在内部使用时区感知日期对象,并且在模板和表单中转换为最终用户的时区。
如果用户居住在多个时区时,这会很方便。你要根据用户的时间来显示日期信息。
即便你的网站只在一个时区可用,在数据库中以 UTC 来存储数据是个好习惯。主要原因是夏令时。很多地方都有夏令时系统,时钟在春季向前调整,秋季向后调整。如果你以当地时间起居,那么时区转换时,每年都可能会遇到两次错误。也许这对你的博客没什么影响,但是每年两次,一次一小时多收或是少收用户的费用,这就是个问题。解决办法就是在代码里使用 UTC,并且在与最终用户交互时,使用当地时间。
Changed in Django 3.2:
Support for non-pytz timezone implementations was added.
Naive 日期对象与 Aware 日期对象
Python 的 datetime.datetime 对象有一个 tzinfo 属性,它可以存储时区信息,表示为 datetime.tzinfo 子类的一个实例。当设置这个属性并描述了偏移量后,日期对象就是 aware 的,否则就是 naive 的。
你可以使用 is_aware() 和 is_naive() 来决定日期是 aware 还是 naive 的。
当关闭了时区支持,Django 会在本地时间里使用原生日期对象。这对很多用例来说足够了。在这个模式下,如果你想获取当前时间,你可以这么写:
import datetime
now = datetime.datetime.now()
当启用了时区支持 (USE_TZ=True) ,Django 使用 time-zone-aware 日期对象。如果你的代码创建了日期对象,她们应该也是 aware 的。在这个模式下,上面的例子变成:
from django.utils import timezone
now = timezone.now()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。