Как вернуться к использованию нескольких языков в Django во время выполнения?

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

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

Для данного запроса на страницу:

  1. Найдите естественный язык пользователя (например, немецкий)
  2. Найдите отрасль пользователя (например, оценка обучения)
  3. Активируйте немецкий язык / язык оценки успеваемости (например, translation.activate ("обучение-оценка-де")

Файл .po "Learning-Assessment-de" будет переводить только подмножество всех строк в проекте, потому что он предназначен только для перевода определенной отраслевой терминологии.

Это вопрос:

Когда строка отсутствует, я хочу, чтобы Django вернулся к немецкому языку (определенному на шаге № 1 выше), а не к английскому (язык по умолчанию в моем settings.py).

Мои файлы .po на английском / немецком языках по умолчанию относятся к определенной отрасли.

Это возможно?


person djsmith    schedule 02.09.2013    source источник
comment
Я не понимаю, если строка не отсутствует в файле .po, то где еще она может отсутствовать?   -  person yuvi    schedule 02.09.2013
comment
Интересно, что, похоже, лучше всего будет создавать пользовательский gettext, который может получить объект запроса ´gettext ('Hello world', request) ´.   -  person Mario César    schedule 04.09.2013


Ответы (1)


Я думаю, что это возможно, и один из самых быстрых способов сделать это (даже если проверить, работает ли он) - это обезвредить модуль перевода Django, чтобы добавить поддержку резервного языка, подобную этой (не проверено):

from django.utils.translation import trans_real
... # Import other things


# Added `fallback_language` parameter
def do_translate(message, translation_function, fallback_language=None):
    """
    Translates 'message' using the given 'translation_function' name -- which
    will be either gettext or ugettext. It uses the current thread to find the
    translation object to use. If no current translation is activated, the
    message will be run through the default translation object.
    """
    global _default

    # str() is allowing a bytestring message to remain bytestring on Python 2
    eol_message = message.replace(str('\r\n'), str('\n')).replace(str('\r'), str('\n'))
    t = getattr(_active, "value", None)
    if t is not None:
        result = getattr(t, translation_function)(eol_message)
    else:

        # Use other language as fallback.
        if fallback_language is not None:
            fallback = translation(fallback_language)
            result = getattr(_default, translation_function)(eol_message)

        else:
            if _default is None:
                from django.conf import settings
                _default = translation(settings.LANGUAGE_CODE)
            result = getattr(_default, translation_function)(eol_message)
    if isinstance(message, SafeData):
        return mark_safe(result)
    return result

# Added `fallback_language` parameter
def do_ntranslate(singular, plural, number, translation_function, fallback_language=None):
    global _default

    t = getattr(_active, "value", None)
    if t is not None:
        return getattr(t, translation_function)(singular, plural, number)

    # Use other language as fallback.
    if fallback_language is not None:
       fallback = translation(fallback_language)
       return getattr(fallback, translation_function)(singular, plural, number)

    if _default is None:
        from django.conf import settings
        _default = translation(settings.LANGUAGE_CODE)
    return getattr(_default, translation_function)(singular, plural, number)


# Override Django functions with custom ones.
trans_real.do_translate = do_translate
trans_real.do_ntranslate = do_ntranslate

Две указанные выше функции взяты из модуля django.utils.translation.trans_real. Просто добавил несколько строк к этим функциям. Вам также потребуется изменить другие функции (например, gettext, ngettext, pgettext), чтобы принять параметр fallback_language и передать его двум указанным выше. Пожалуйста, попробуйте, работает ли этот код.

Обратите внимание, что исправление обезьяны распространяется на весь проект - оно влияет на все ваше приложение, а также сторонние приложения. В качестве альтернативы вы можете взять исходный код модуля django.utils.translation.trans_real в качестве основы для создания пользовательских функций перевода, которые будут использоваться только в нескольких местах вашего приложения.

person HankMoody    schedule 06.09.2013