Переключение Django, для блока кода, переключает язык, поэтому переводы выполняются на одном языке

У меня есть проект django, который использует рабочий процесс, который отправляет письма пользователям. Рабочие процессы слушают сервер rabbitmq и получают всю информацию о отправляемом электронном письме, переменных шаблона, адресе электронной почты для отправки и т.д. Тело письма создается с помощью шаблонов django и render_to_string.

Однако я хочу интернационализировать это. Некоторые из наших пользователей будут использовать веб-сайт на английском языке, некоторые на других языках. Они должны получать электронные письма на своем языке. Я попытался обработать рабочий процесс электронной почты (используя django.utils.translations.ugettext/ugettext_lazy), чтобы тема электронной почты и адрес электронной почты _ (...) или {% blocktrans%} и

Однако, поскольку электронная почта отображается и отправляется в другом фоновом рабочем процессе, нормальный процесс определения языка django, похоже, не применяется. Для этого нет сеанса пользователя, нет файлов cookie или нет заголовков HTTP. При отправке сообщения на сервер rabbitmq я могу сохранить код языка

Но, как мне сообщить django/gettext, чтобы использовать этот язык в точке.

например. Моя функция, отправляющая электронную почту, может выглядеть так:

def send_email(details):
  lang = details['lang']
  name = details['name']
  email_address = details['email_address']

  switch_gettext_to_this_language_what_goes_here(lang):
  # ?????
  email_subject = _("Welcome to $SITE")  

Что мне нужно, чтобы переключить django translations/gettext на конкретный код языка, чтобы _() использовал этот код языка?

Ответ 1

Самый простой способ переключения языка:

from django.utils.translation import activate
activate('en')
# do smthg
activate('pl')
# do something in other language

будьте осторожны с этим, поскольку это изменяет контекст для остальной части выполнения этого процесса/потока.

Ответ 2

Как отметил @SteveMayne в комментарии (но стоит ответить), теперь вы можете использовать диспетчер контекста translation.override (работает с Django 1.6, не проверял с более ранними версиями):

from django.utils import translation
print(_("Hello"))  # Will print to Hello if default = 'en'

# Make a block where the language will be Danish
with translation.override('dk'):
    print(_("Hello"))  # print "Hej"

В основном он использует то же самое, что и ответ @bitrut, но он встроен в Django, поэтому он делает меньше зависимостей...

Ответ 3

Вы можете принудительно использовать язык с помощью диспетчера контекстов:

class force_lang:
    def __init__(self, new_lang):
        self.new_lang = new_lang
        self.old_lang = translation.get_language()
    def __enter__(self):
       translation.activate(self.new_lang)
    def __exit__(self, type, value, tb):
       translation.activate(self.old_lang)

Затем вы можете использовать оператор with:

with force_lang('en'):
    ...

Ответ 4

Это довольно просто, используя django-i18next (https://pypi.python.org/pypi/django-i18next).

Загрузите templatetags.

{% load i18n i18next %}

Следующий код заставляет голландский языковой стандарт использовать все, что помещается внутри блока overridelocale.

{% overridelocale 'nl' %}
    <p>
        <a href="/login/">{% trans "Log in" %}</a>
    </p>
{% endoverridelocale %}

Следующий код заставляет русский язык использовать все, что помещается внутри блока overridelocale.

{% overridelocale 'ru' %}
    <p>
        <a href="/login/">{% trans "Log in" %}</a>
    </p>
{% endoverridelocale %}

Следующий код заставляет локальный язык английского языка быть помещенным внутри блока overridelocale.

{% overridelocale 'en' %}
    <p>
        <a href="/login/">{% trans "Log in" %}</a>
    </p>
{% endoverridelocale %}

Ответ 5

Выключает django docs объясняет, как:

В то время как Django предоставляет богатый набор инструментов i18n для использования в представлениях и шаблонах, он не ограничивает использование кода, специфичного для Django. Механизмы перевода Django могут использоваться для перевода произвольных текстов на любой язык, поддерживаемый Django (если существует соответствующий каталог переводов, конечно). Вы можете загрузить каталог переводов, активировать его и перевести текст на язык по вашему выбору, но не забудьте вернуться к исходному языку, так как активация каталога переводов выполняется по потоку, и такое изменение повлияет на код, запущенный в том же потоке.