Содержание
Данная глава временно взята из первой версии книги и подлежит корректировке. Вы можете помочь с этим!
Перевод © Кравцов Даниил <danilaru • ms • tusur • ru>
Редактирование © Попов Руслан <radz • yandex • ru>
Django изначально разрабатывался в центре США (буквально: Лоуренс, штат Канзас, это в 65 км от географического центра континентального США). Несмотря на это, подобно большинству проектов с открытыми исходными текстами сообщество Django включает людей со всего мира. По мере того как это сообщество охватывало разных людей, аспекты интернационализации и локализации становились чрезвычайно важными. Так как множество разработчиков имеют в лучшем случае нечёткое понимание этих терминов, мы кратко их рассмотрим.
Интернационализация относится к процессу проектирования программ для потенциального использования с любым языком. Это включает в себя выделение текста (как элементы интерфейса, так и сообщения об ошибках) для будущего перевода, абстракцию даты и времени для вывода в различных стандартах, предоставляя поддержку для различных временных зон, а самое главное — уверенность, что код не содержит предположений о стране проживания пользователей. Вы часто видите термин «internationalization» сокращённый как I18N (число 18 — это количество букв между первой «I» и последней «N»).
Локализация относится к процессу фактического перевода программ подвергшихся интернационализации для использования в конкретной локали. Вы иногда будете встречать аббревиатуру L10N для обозначения термина «локализация».
Сам Django полностью интернационализирован. Все строки готовы для перевода, а настройки управляют отображением значений, зависимых от локали, таких как время и дата. С Django поставляется более чем 40 различных файлов локализации. Если английский язык не является для вас родным, очень вероятно, что Django уже переведён на ваш язык.
Та же среда интернационализации, использованная для осуществления такого перевода, доступна вам для перевода вашего приложения.
С точки зрения разработчика, вам потребуется добавить минимальное количество обработчиков в ваш исходный код и в шаблоны. Такие обработчики называются строками перевода. Они указывают Django, что «Этот текст нужно переводить на язык пользователя, если перевод этого текста доступен для данного языка.»
Django принимает во внимание эти обработчики при переводе приложений на лету, с учётом пользовательских настроек.
По существу: Django делает две вещи:
Позволяет разработчикам и авторам шаблонов указывать какие именно части приложений нуждаются в переводе.
Использует эту информацию для перевода приложений для определённого пользователя, согласно его языковым настройкам.
Замечание
Механизм переводов Django использует GNU gettext (http://www.gnu.org/software/gettext/) через стандартный модуль gettext, поставляемый с интерпретатором Python.
Если вам не требуется интернационализация
Обработчики интернационализации Django включены по умолчанию, что приводит к небольшому повышению расходования ресурсов. Если вы не желаете использовать интернационализацию, вам нужно назначить параметру USE_I18N значение False в вашем файле настроек. В этом случае Django применит некоторую оптимизацию и не будет загружать механизм интернационализации.
Возможно вы также пожелаете удалить django.core.context_processors.i18n из параметра TEMPLATE_CONTEXT_PROCESSORS.
Строки перевода указывают, что «Этот текст надо перевести». Эти строки могут использоваться в коде и в шаблонах. Вашей задачей будет выделение таких строк, а система будет переводить выделенные вами строки и только их.
Помечайте строки для перевода, используя функцию
_()
. (Да, имя функции — символ
нижнего подчеркивания). Для подключения этой функции
используйте:
from django.utils.translation import gettext_lazy as _
В этом примере, текст, «Welcome to my site.» помечен для перевода:
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)
Функция
django.utils.translation.gettext()
идентична _()
. Этот пример эквивалентен
предыдущему:
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)
(Недостаток использования переменных или вычисляемых значений, как показано в предыдущих двух примерах, в том, что стандартная утилита поиска текста подлежащего переводу, make-messages.py, не сможет найти такие строки. Подробности по этой утилите будут дальше.)
Строки, передаваемые в _()
или
gettext()
, могут содержать символы
подстановки, указанные в соответствии со стандартом языка
Python, например:
def my_view(request, n):
output = _('%(name)s is my name.') % {'name': n}
return HttpResponse(output)
Эта технология позволяет осуществлять перевод, привязанный к особенностям языка, перемещая символы подстановки в тексте. На пример, строка на английском «Adrian is my name.», может переведена на испанский как «Me llamo Adrian.», используя символ подстановки установленный после переводимого текста, а не перед ним.
По этой причине, вы должны использовать именованную подстановку вместо позиционной (%s или %d). Если вы используете позиционную подстановку, переводчик не сможет поменять местами подстановки.
Используйте функцию
django.utils.translation.gettext_noop()
для того, чтобы отметить строки для перевода, но без
осуществления перевода в данный момент. Строки помеченный
таким образом не переводятся до самого последнего момента.
Используйте этот подход, если у вас есть неизменные строки, которые должны быть сохранены на оригинальном языке — такие как строки в базе данных — но которые должны быть переведены в последний момент, например, когда строка показывается пользователю.
Используйте функцию
django.utils.translation.gettext_lazy()
для отложенного перевода строк — это когда значение
получают до того, как будет вызвана функция.
Например, для пометки атрибута поля help_text как подлежащего переводу сделайте следующее:
from django.utils.translation import gettext_lazy
class MyThing(models.Model):
name = models.CharField(help_text=gettext_lazy('This is the help text'))
В данном примере функция gettext_lazy()
сохраняет отложенную ссылку на строку, а не её перевод. Сам
перевод будет выполнен в момент использования строки,
например, при обработке шаблона на сайте администратора
Django.
Если вам не нравится длинное имя функции, вы можете использовать _ (символ подчёркивания), вот так:
from django.utils.translation import gettext_lazy as _
class MyThing(models.Model):
name = models.CharField(help_text=_('This is the help text'))
Всегда используйте отложенные переводы в моделях (иначе они не
будут переведены корректно для каждого отдельного
пользователя). Будет хорошей идеей добавлять перевод к именам
полей и таблиц тоже. Это означает, что необходимо явно
указывать опции verbose_name и
verbose_name_plural в классе
Meta
:
from django.utils.translation import gettext_lazy as _
class MyThing(models.Model):
name = models.CharField(_('name'), help_text=_('This is the help text'))
class Meta:
verbose_name = _('my thing')
verbose_name_plural = _('mythings')
Используйте функцию
django.utils.translation.ngettext()
для определения сообщений, которые имеют различные формы
единственного и множественного числа, например:
from django.utils.translation import ngettext
def hello_world(request, count):
page = ngettext(
'there is %(count)d object',
'there are %(count)d objects', count
) % {'count': count}
return HttpResponse(page)
Функция ngettext()
принимает три
аргумента: строку для единственного числа, строку для
множественного числа и количество объектов (которые передаются
языку перевода в виде переменной count
.
2 комментария | Оставьте комментарий
Доброго,
как использовать перевод для строк юникода?
Как сделать так?
GENDER_CHOICES = (
(u'М', _(u'Мужской')),
(u'Ж', _(u'Женский')),
(u'Н', _(u'Не определён')))
Ответ на oildollar
Доброго,
как использовать перевод для строк юникода?
Как сделать так?
GENDER_CHOICES = (
(u'М', _(u'Мужской')),
(u'Ж', _(u'Женский')),
(u'Н', _(u'Не определён')))
Так же как и для обычный строк. В документации описано, вроде даже переведено на русский.
P.S.: Вопросы задавайте на форуме.