Функции ugettext и ugettext_lazy, не распознаваемые make-сообщениями в Python, Django

Я работаю с Django 1.5.1 и испытываю "странное поведение" с переводами. я использую ugettext а также ugettext_lazy в том же файле Python. Если я организую импорт как:

from django.utils.translation import ugettext as trans
from django.utils.translation import ugettext_lazy as _

или же

from django.utils.translation import ugettext as trans, ugettext_lazy as _

Строки помечены как trans("string") пропускаются при запуске makemessages команда.

Однако, если я не переименую ugettext хорошо работает с обеими версиями:

from django.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _

или же

from django.utils.translation import ugettext, ugettext_lazy as _

Сейчас trans("string") работает хорошо.

Итак, кто-нибудь знает, почему это переименование импорта приводит к тому, что переименованная функция не вызывается? Действительно ли это "ограничение" Python, которое я не знал, когда переименовывал более одной функции внутри одного модуля?


ОБНОВИТЬ

После некоторого тестирования я понял, что даже создание пустого модуля python внутри приложения со следующим кодом не работает:

from django.utils.translation import ugettext_lazy as translate

a = translate("string")

Однако при использовании _ для псевдонима это работает:

from django.utils.translation import ugettext_lazy as _

a = _("string")

Мой вывод: вы можете использовать только _ псевдоним для ugettext а также ugettext_lazy (или любая другая связанная функция перевода) в Django, иначе она не будет распознана makemessages командование Техническое объяснение можно найти в ответе Роберта Лужо.

Спасибо!

5 ответов

Решение

Командная утилита Django makemessages внутренне вызывает программу xgettext следующим образом:

cmd = (
    'xgettext -d %s -L Python %s %s --keyword=gettext_noop '
    '--keyword=gettext_lazy --keyword=ngettext_lazy:1,2 '
    '--keyword=ugettext_noop --keyword=ugettext_lazy '
    '--keyword=ungettext_lazy:1,2 --keyword=pgettext:1c,2 '
    '--keyword=npgettext:1c,2,3 --keyword=pgettext_lazy:1c,2 '
    '--keyword=npgettext_lazy:1c,2,3 --from-code UTF-8 '
    '--add-comments=Translators -o - "%s"' %
    (domain, wrap, location, work_file))

(источник можно найти здесь). Итак, некоторые ключевые слова предопределены утилитой xgettext (проверьте ссылку на --keyword):

  • для python - gettext, ugettext, dgettext, ngettext, ungettext, dngettext, _

а некоторые добавляются утилитой django:

  • gettext_lazy, ngettext_lazy, ugettext_noop, ugettext_lazy, ungettext_lazy, pgettext, npgettext, pgettext_lazy, npgettext_lazy

Ключевое слово trans не входит ни в один из этих наборов ключевых слов, поэтому его не следует использовать для маркировки текстов при переводах.

Неожиданные псевдонимы ugettext могут быть обработаны путем переопределения makemessages команда, такая как в:

from django.core.management.commands import makemessages

class Command(makemessages.Command):
    """
    Extends the makemessages command to look for additional aliases.
    """
    xgettext_options = makemessages.Command.xgettext_options + ['--keyword=_lazy']

См. https://docs.djangoproject.com/en/1.8/topics/i18n/translation/.

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

Некоторые предупреждения в этих заметках:

  • Каждый шаблон для вашего веб-сайта должен загружать библиотеку тегов i18n, используя {% load %}

  • Вам нужно создать каталог локали вручную перед запуском makemessages - что вы обычно делали, если нет, вы получаете сообщение об ошибке

  • Языковые файлы должны быть скомпилированы в .mo файлы, прежде чем использовать их - что вы также сделали

РЕДАКТИРОВАТЬ

На странице, на которую я ссылаюсь на свой пост, они используют этот синтаксис в шаблонах:

{% trans "Hello" %}

это то, что вы уже пробовали?

Еще один способ решить проблему создания файлов .po — это сервер разработки.

Во время работы моего сервера разработки я выполнил команду makemessage. Вывод команды был правильным, но мои файлы .po были обновлены:

      (venv_crypto_bot) macbook-pro:django_project dauzon$ python manage.py makemessages -a 
processing locale fr
processing locale en
processing locale ru

Остановите сервер разработки и повторно запустите команду, чтобы решить мою проблему.

Вы можете создать свою команду, чтобы вызвать оригинал compilemessagesкоманда с дополнительными аргументами.

Например, для поддержки from django.utils.translation import pgettext_lazy as _p:

      # Created by BaiJiFeiLong@gmail.com at 2022/4/20
from django.core.management import call_command
from django.core.management.base import BaseCommand
from django.core.management.commands import makemessages


class Command(BaseCommand):
    help = "Make messages in en_US and zh_CN, support _p, ignore venv folder."

    def handle(self, *args, **options):
        text = "-l en_US -l zh_CN --ignore ?env -v3"
        command = makemessages.Command()
        getattr(command, "xgettext_options").append("--keyword=_p:1c,2")
        call_command(command, *text.split())

Заметки:

_p:1c,2представляет собой _p('msgctxt', 'msgid'), функция с двумя аргументами, например pgettext_lazy

Другие вопросы по тегам