Django gettext translation не работает с dinamic translations

Вопрос:

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

Что у меня есть: Я установил несколько языков в settings.py (LANGUAGES) и настроил, чтобы языком по умолчанию был английский (LANGUAGE_CODE = 'en'). Я использую аутентификацию на основе токенов (rest_framework.authtoken) для аутентификации пользователей. Предпочтительный язык пользователя хранится в базе данных как preferred_language. Я добавил пользовательское промежуточное ПО для обработки переключения языка на основе предпочтений пользователя, которое должно применяться сразу после аутентификации пользователя и установки сессии. Проблема: Предпочтение языка, похоже, применяется для статического содержимого (например, шаблонов), но динамические переводы для строк в представлениях (с помощью gettext) не применяются корректно после установки предпочтительного языка пользователя. Например, хотя смена языка работает частично (например, для содержимого пользовательского интерфейса), сообщения, созданные с помощью gettext() (например, сообщения об ошибке или успехе), по-прежнему отображаются на языке по умолчанию (en), а не на предпочтительном языке пользователя (например, es для испанского). Вот некоторые наблюдения:

Когда я проверяю активный язык в представлении с помощью get_language(), он правильно отражает предпочтительный язык для сессии. Я проверил, что предпочтительный язык правильно установлен как в сессии, так и в cookie (cookie_language_tinocoloco). LocaleMiddleware настроен на активацию языка, но он не применяется к динамическим сообщениям. Что я пробовал: Я убедился, что порядок промежуточного ПО правильный. SessionMiddleware находится перед LocaleMiddleware, а LocaleMiddleware находится перед AuthenticationMiddleware, что соответствует рекомендуемой настройке. Я вручную активировал язык в промежуточном ПО с помощью translation.activate(user.preferred_language). Моя настройка: Конфигурация MIDDLEWARE (соответствующий фрагмент):


MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",  # Ensuring session is set before locale
    "django.middleware.locale.LocaleMiddleware",  # Language activation middleware
    "django.contrib.auth.middleware.AuthenticationMiddleware",  # Authentication for token
    # Other middleware
]
Custom Language Middleware:

from django.utils import translation

def get_user_language(user):
    if user and hasattr(user, 'preferred_language') and user.preferred_language:
        return user.preferred_language
    return None

class LanguageMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        if hasattr(request, 'user') and request.user.is_authenticated:
            language = get_user_language(request.user)
            if language:
                translation.activate(language)  # Activate user preferred language
        response = self.get_response(request)
        return response

Session Cookie: Я также убеждаюсь, что языковые предпочтения хранятся в сессии и cookie.

Ожидаемое поведение: Я ожидаю, что динамические переводы (с помощью gettext() и gettext_lazy()) будут меняться в зависимости от предпочитаемого пользователем языка. Однако, несмотря на установку правильных языковых предпочтений, только некоторые части сайта (например, шаблоны) отражают новый язык, в то время как другие (например, динамически генерируемые сообщения) по-прежнему отображаются на языке по умолчанию (en).

Вопрос: Не хватает ли в моей настройке чего-то, что позволило бы динамическим строкам перевода учитывать предпочтительный язык аутентифицированного пользователя? Как обеспечить глобальное применение переводов, включая динамические сообщения, после установки языка пользователя в сессии и куках? Любое руководство или совет по этому вопросу будут очень признательны. Спасибо!

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

Для примера приведем фрагмент из проекта Django с настроенными переводами:

In [2]: from django.utils.translation import gettext, gettext_lazy, activate

In [3]: foo = gettext("Cows")

In [4]: bar = gettext_lazy("Cows")

In [5]: activate('ta')

In [6]: foo2 = gettext("Cows")

In [7]: bar2 = gettext_lazy("Cows")

In [8]: print("foo =", foo, "bar =", bar, "foo2 =", foo2, "bar2 =", bar2)

foo = Cows bar = பசுக்கள் foo2 = பசுக்கள் bar2 = பசுக்கள்

Здесь видно, как gettext() получает текст сразу, а gettext_lazy() ждет, пока он будет оценен (т.е. когда он будет напечатан).

Таким образом, если вы используете gettext_lazy() вместо gettext(), то ваши строки будут оцениваться только во время рендеринга ответа, и это должно заставить его использовать правильную переведенную строку. Надеюсь, это поможет.

Вернуться на верх