Интернационализация и локализация django

На примере русского языка.

  1. В файл settings.py вписываем:

    LANGUAGE_CODE = 'ru'
    
    LANGUAGES = (
    	('ru', 'Russian'),
    	('en', 'English'),
    )
    
    MIDDLEWARE_CLASSES = (
        'django.middleware.common.CommonMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.locale.LocaleMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
    )
    
  2. Подготавливаем все фразы к переводу.
    Для этого в .py-файлах:

    from django.utils.translation import ugettext as _
    ...
    jsonDict["message"] = _("no data received")
    

    а в шаблонах есть теги для перевода фраз и многострочного перевода:

    {% load i18n %}
    
    {% trans "Login" %}
    
    {% blocktrans count object.sets as sets %}{{ sets }} set{% plural %}{{ sets }} sets{% endblocktrans %}
    

    Лучше обходиться без начальных и оконечных пробелов, т.к. в противном случае перевод может не подцепиться.

    К сожалению, в каждом шаблоне нужно добавлять загрузку i18n, сразу после тега {% extends «layout.html» %}, почему-то разработчики джанго считают это фичей, видимо, потому что не пользуются).

    Перевод полей модели:

    from django.utils.translation import ugettext_lazy as _
    ...
    birthday = models.DateField(blank = True, null = True, verbose_name = _('Birthday'))
    

    Перевод полей форм:

    from django.utils.translation import ugettext as _
    ...
    pass1 = forms.CharField(widget = forms.PasswordInput, label = _("Password"), min_length = 6, max_length = 30)
    
  3. В корне проекта создаём папку locale
  4. Из корня проекта запускаем команду

    django-admin makemessages -l ru -a
    

    Команда генерирует файл django.po.
    Сначала идёт заголовок, в котором нет ничего интересного, за исключением следующих строк:

    "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
    "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
    

    По этому правилу образовываются формы слов русского языка во множественном числе.
    Дальше следуют пачки вида

    #: main/views.py:341
    msgid "no data received"
    msgstr "данные не переданы"
    

    где первая строка — место, где встретилась фраза, помеченная для перевода, вторая строка — фраза, а третья — перевод, который надо вписать.
    Особый случай — переводы, зависящие от числа, к примеру, подходов:

    #: templates/.../list.html:17
    msgid "%(sets)s set"
    msgid_plural "%(sets)s sets"
    msgstr[0] "%(sets)s подход"
    msgstr[1] "%(sets)s подхода"
    msgstr[2] "%(sets)s подходов"
    

    здесь для русского языка нужно задать три фразы — для значения переменной 1, 2 и 5.

  5. Скомплировать переводы

    django-admin.py compilemessages
    

    По необходимости пункты 4-5 можно повторять, при этом уже введённые переводы не будут потеряны, если фразы, помеченные к переводу, не были удалены.

    Джанго определяет язык пользователя так (если не нашёл, то идёт дальше):

    1. Ищет ключ django_language в сессии пользователя
    2. Ищет в cookies
    3. Ищет в cookies
    4. Ищет Accept-Language в HTTP-заголовках, и пытается отыскать разрешённые в приложении (в переменной LANGUAGES) языки
    5. Использует значение переменной LANGUAGE_CODE

Для смены локали нужно следующее:

  1. В urls.py прописать url

    url(r'^i18n/', include('django.conf.urls.i18n')),
    

    смена локали будет доступна по адресу /i18n/setlang/

  2. Где-нибудь в шаблоне определить форму:

    {% trans 'Change your locale' %}:
    <form action="/i18n/setlang/" method="POST">
    	{% csrf_token %}
    	<input name="next" type="hidden" value="/accounts/profile/" /><br/>
    	<select name="language">
    		{% for lang in LANGUAGES %}
    			<option value="{{ lang.0 }}">{{ lang.1 }}</option>
    		{% endfor %}
    	</select><br/>
    	<input type="submit" value="{% trans 'change' %}" />
    </form>
    

Ссылка на официальную документацию по интернационализации django.

Локализация javascript в django

17 комментариев so far.

  1. Ильшат:
    Спасибо за статью! Все по полочкам.
    Этот подход может помочь со склонением месяца при выводе даты?
    • bullgare:
      К сожалению, со склонениями я не разобрался пока (мне пока не надо было).
      Если кто посоветует — буду благодарен.
      Из банального — фразы для перевода писать с суффиксами, и переводить их и на английский тоже (чтобы убрать суффикс).
  2. Влад:
    Здравствуйте! У меня получается пустая форма для выбора языка. В settings.py список языков указан, но почему-то в форму не попадает. Что может быть не так?
  3. ManulCat:
    В некоторых случаях (nginx + uwsgi + django 1.4.5) может понадобится добавить в файл settings.py:

    LOCALE_PATHS = (
    ‘полный путь к каталогу locale проекта’,
    )

  4. msblast:
    Влад, нужно ещё в TEMPLATE_CONTEXT_PROCESSORS добавить
    ‘django.core.context_processors.i18n’.
  5. Selena:
    Добрый день! Если Вы заинтересованы в локализации web-ПО, ПО для персональных компьютеров, ПО для мобильных устройств либо иного вида программного обеспечения, я рекомендую Вам использовать этот инструмент на базе web: https://poeditor.com/ POEditor является интуитивным, хорошо проработанным инструментом, обладающим рядом полезных свойств, которые помогают организовать процесс управления переводом. Он поддерживает множество популярных форматов файлов и обладает собственным API, что обеспечивает лучшую автоматизацию. Желаю Вам больших успехов в Ваших проектах!
  6. Alex Laban:
    ааа… все! сообразил!!
    у меня тут есть еще одна апликация (3rd party), у которой тоже есть своя локализация ru…
    тогда вопрос меняется ;)
    как «склеивать» мою и 3rd party локализации?
  7. Артём:
    Добрый день.
    Можете сделать видео как это все настроить правильно самого начала
  8. Kirill:
    и с чем работаете?
  9. Kirill:
    да просто интересно) а на гошечку перешли?

LEAVE A COMMENT