简体   繁体   English

Python 中的 makemessages 无法识别 ugettext 和 ugettext_lazy 函数 Django

[英]ugettext and ugettext_lazy functions not recognized by makemessages in Python Django

I'm working with Django 1.5.1 and I'm experiencing some "strange behaviour" with translations.我正在使用 Django 1.5.1,我在翻译时遇到了一些“奇怪的行为”。 I'm using ugettext and ugettext_lazy in the same Python file.我在同一个 Python 文件中使用ugettextugettext_lazy If I organize the imports as:如果我将进口组织为:

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

or或者

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

The strings marked as trans("string") are skipped when running makemessages command.运行makemessages命令时将跳过标记为trans("string")的字符串。

However, if I don't rename the ugettext it works well with both versions:但是,如果我不重命名ugettext ,它适用于两个版本:

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

or或者

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

Now trans("string") works well.现在trans("string")运行良好。

So, does anybody know why this import renaming is causing the renamed function not to be called?那么,有人知道为什么这个导入重命名导致重命名的 function 不被调用吗? Is this an actual Python "limitation" I didn't know when renaming more than one function inside the same module?这是一个实际的 Python “限制”吗?我在同一模块内重命名多个 function 时不知道?


UPDATE更新

After some testing, I've realized that even creating an empty python module inside an app with the following code it doesn't work:经过一些测试,我意识到即使使用以下代码在应用程序中创建一个空的 python 模块也不起作用:

from django.utils.translation import ugettext_lazy as translate

a = translate("string")

However, if using _ for the alias it works:但是,如果使用_作为别名,它会起作用:

from django.utils.translation import ugettext_lazy as _

a = _("string")

My conclusion is: You can only use the _ alias for ugettext and ugettext_lazy (or any other related translation function) in Django or else it won't be recognized by makemessages command .我的结论是:您只能在 Django 中为ugettextugettext_lazy (或任何其他相关翻译函数)使用_别名,否则makemessages命令无法识别它 The technical explanation can be found in Robert Lujo's answer.技术解释可以在 Robert Lujo 的回答中找到。

Thanks!谢谢!

Django command utility makemessages internally calls xgettext program like this: 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))

(source can be found here ). (来源可以在这里找到)。 So, some keywords are predefined by the xgettext utility (check reference for --keyword):因此,一些关键字是由xgettext实用程序预定义的(检查 --keyword 的参考):

  • for python - gettext, ugettext, dgettext, ngettext, ungettext, dngettext, _对于 python - gettext、ugettext、dgettext、ngettext、ungettext、dngettext、_

and some are added by django utility:有些是由 django 实用程序添加的:

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

Keyword trans is not in any of these keyword sets, so you should not use it for marking texts for translations.关键字trans不在这些关键字集中,因此您不应使用它来标记要翻译的文本。

Unexpected ugettext aliases can be handled by overriding the makemessages command, such as in:可以通过覆盖makemessages命令来处理意外的 ugettext 别名,例如:

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']

See https://docs.djangoproject.com/en/1.8/topics/i18n/translation/#customizing-the-makemessages-command请参阅https://docs.djangoproject.com/en/1.8/topics/i18n/translation/#customizing-the-makemessages-command

These notes about multi-language support for Django project may let you identify what is wrong.这些关于Django 项目多语言支持的说明可能会让您识别出问题所在。 Most probably renaming is not the root cause for failure.很可能重命名不是失败的根本原因。

Some warnings in these notes:这些注释中的一些警告:

  • Each template for your web site must load the i18n tag library using the {% load %}您网站的每个模板都必须使用{% load %}加载 i18n 标记库

  • You need to create the locale directory manually before running makemessages - that you normally did, if not you get an error message您需要在运行 makemessages 之前手动创建语言环境目录 - 您通常会这样做,否则您会收到错误消息

  • Language files must be compiled to .mo files before you use them - that you did also语言文件在使用之前必须编译为.mo文件 - 你也这样做了

EDIT编辑

In the page i linked to my post, they are using this syntax in templates:在我链接到我的帖子的页面中,他们在模板中使用以下语法:

{% trans "Hello" %}

is it something you tried already ?这是你已经尝试过的吗?

Another way for resolving no .po files generation are the development server.解决没有 .po 文件生成的另一种方法是开发服务器。

During my development server is running I executed the command makemessage .在我的开发服务器运行期间,我执行了命令makemessage Command output was right, but my .po files were updated :命令输出是正确的,但我的 .po 文件已更新:

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

Stop the development server and re-run the command resolves my issue.停止开发服务器并重新运行该命令可以解决我的问题。

You can create your own compilemessages command, to call the original compilemessages command with extra arguments.您可以创建自己的compilemessages命令,以调用带有额外 arguments 的原始compilemessages命令。

For example, to support from django.utils.translation import pgettext_lazy as _p :例如,要支持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())

Notes:笔记:

_p:1c,2 represents _p('msgctxt', 'msgid') , function with two arguments like pgettext_lazy _p:1c,2代表_p('msgctxt', 'msgid') , function 和两个 arguments like pgettext_lazy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM