Регистрация неправильных переводов в Django

Я часто сталкиваюсь с ошибкой использования gettext в контексте, где фактический язык еще не установлен - вместо того, чтобы использовать соответствующий gettext_lazy.

Такие ошибки бывает трудно отловить - я бы хотел сделать их более заметными, ведя соответствующий журнал или, возможно, даже бросая исключения.

  • Будет ли правильным написать функцию-обертку, которая регистрирует ошибку в случае get_language() is None?
  • Тогда, конечно, нужно будет обеспечить, чтобы эта обертка использовалась всегда - вводится еще одна тонкая легкодоступная ошибка. В общем, я полагаю, что можно использовать обезьяньи исправления, но я бы хотел избежать этого, если возможно. Вся диспетчеризация за django.util.translation кажется уже достаточно сложной. Есть ли чистый способ подключить эту функциональность?

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

Один из вариантов, который вы можете рассмотреть, это использование пользовательского промежуточного ПО или пользовательского контекстного процессора для установки языка для текущего запроса. Затем вы можете использовать функцию get_language для проверки того, был ли установлен язык, и вызвать исключение или записать ошибку, если нет.

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

from django.utils import translation

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

def __call__(self, request):
    # Set the language for the current request
    language = request.GET.get('language')
    if language:
        translation.activate(language)
        request.LANGUAGE_CODE = translation.get_language()
    else:
        request.LANGUAGE_CODE = None

    response = self.get_response(request)

    # Deactivate the language for the current request
    translation.deactivate()

    return response

Затем вы можете использовать атрибут request.LANGUAGE_CODE, чтобы проверить, был ли установлен язык для текущего запроса. Если это None, вы можете поднять исключение или записать ошибку в журнал.

Вот пример того, как можно реализовать пользовательский контекстный процессор, чтобы сделать то же самое:

from django.utils import translation

def language_processor(request): # Установите язык для текущего запроса language = request.GET.get('language') if language: translation.activate(language) request.LANGUAGE_CODE = translation.get_language() else: request.LANGUAGE_CODE = None

# Return the language code as a context variable
return {'LANGUAGE_CODE': request.LANGUAGE_CODE}

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

Для этого можно использовать встроенные проверки Django. Django предоставляет функцию check_for_language, которая вызывает исключение LanguageStoreNotAvailable, если язык не установлен. Вы можете использовать эту функцию в своем коде для проверки доступности языка перед вызовом gettext или gettext_lazy.

from django.utils.translation import check_for_language, gettext

def my_function():
    check_for_language()
    return gettext('Hello, world!')

Если язык не установлен, это вызовет исключение LanguageStoreNotAvailable.

В качестве альтернативы можно использовать функцию gettext_lazy от Django, которая возвращает объект TranslatableString, который будет переведен при отображении в шаблоне или при вызове force_text. Это избавляет от необходимости вообще вызывать gettext и гарантирует, что перевод не будет выполнен, пока не будет установлен язык.

from django.utils.translation import gettext_lazy

def my_function():
    return gettext_lazy('Hello, world!')

Это вернет объект TranslatableString, который можно использовать в коде или шаблонах, а перевод будет выполнен при визуализации.

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

Вы можете использовать фреймворк перевода Django для обработки неправильных переводов, с которыми вы сталкиваетесь. Django предоставляет функцию lazy_number в модуле django.utils.translation, которую вы можете использовать для обертывания любого текста, который необходимо перевести. Эта функция возвращает экземпляр LazyObject, который не будет фактически переводить текст, пока не будет установлен язык.

Чтобы использовать lazy_number, вы можете импортировать его, а затем обернуть свой текст в вызов lazy_number. Например:

from django.utils.translation import lazy_number

text = lazy_number("Hello, world!")

Это создаст экземпляр LazyObject, который будет переводить текст "Hello, world!", когда установлен язык.

Если вы хотите заносить в журнал ошибку или выбрасывать исключение, когда язык не установлен, вы можете использовать функцию get_language в модуле django.utils.translation для проверки текущего языка. Если язык не установлен, вы можете записать ошибку в журнал или выбросить исключение.

from django.utils.translation import get_language

def translate_text(text):
    if get_language() is None:
        # Log the error or throw an exception
        pass
    else:
        return lazy_number(text)

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

Также неплохо установить параметр LANGUAGE_CODE в файле настроек вашего проекта Django на язык по умолчанию, который вы хотите использовать. Это гарантирует, что язык всегда будет установлен, даже если пользователь не задал его явно.

Вот пример того, как можно обернуть функцию gettext в пользовательскую функцию, которая проверяет текущий язык и регистрирует ошибку, если он не установлен:

import logging
from django.utils import translation

def safe_gettext(message):
    current_language = translation.get_language()
    if current_language is None:
        logging.error("Current language is not set")
        return message
    return translation.gettext(message)

Чтобы использовать эту функцию, достаточно вызвать ее вместо функции gettext. Например:

from myapp.utils import safe_gettext

def some_view(request):
    greeting = safe_gettext("Hello, world!")
    return HttpResponse(greeting)

Если текущий язык не установлен, эта функция выдаст ошибку и вернет исходное сообщение. В противном случае будет возвращена переведенная версия сообщения.

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

Альтернативно, вы можете переопределить функцию gettext в своем коде с помощью обезьяньего патча, например, так:

import translation
translation.gettext = safe_gettext

Это заменит встроенную функцию gettext на вашу пользовательскую функцию safe_gettext, чтобы она использовалась везде в вашем коде. Однако "обезьяньи" исправления могут быть рискованными и в целом не рекомендуются, так как могут привести к неожиданному поведению и трудноотлаживаемым проблемам.

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