django - 如何返回带有占位符的惰性翻译对象?

标签 django gettext

在我在 Python v2.7.x 上运行的 Django v1.6.5 项目中,我有一个将其配置作为字符串返回的模型。我需要返回的字符串是一个 gettext_lazy 对象,所以我可以用以后需要的任何语言对其进行评估。

from __future__ import unicode_literals
from django.utils.translation import ugettext_lazy as _, string_concat
...

class MyModel(models.Model):

    key = models.CharField(...)
    value = models.CharField(...)

    @property
    def config_str(self):
        return _('some configuration')

这似乎在这些情况下工作正常:
  • 静态字符串:(见上文) - 有效!
  • 字符串连接:return string_concat(self.key, _(' equals '), self.value) - 工作!

  • 什么不起作用,将 gettext_lazy 与占位符一起使用,例如:
    return _('“%(key)s” equals “%(value)s”' % {key: self.key, value: self.value})
    

    或使用 .format() 机制:
    return _('“{key}” equals “{value}”').format(key=self.key, value=self.value)
    

    当我这样做时,我的 .po 文件确实包含:
    #, python-format
    msgid "“%(key)s” equals “%(value)s”" or
    msgid "«{key}» equals «{value}»"
    

    但即使我填充这个例如:
    msgstr "«%(key)s» est égal à «%(value)s»" or
    msgstr "«{key}» est égal à «{value}»"
    

    我运行 compilemessages,翻译似乎被忽略了。当我翻译模型实例返回的promise时,我总是得到一个占位符填充的EN字符串,例如,'“foo”等于“bar”'。请注意,即使第一个调用上下文是 FR(例如),我也会得到一个 EN 字符串。这告诉我翻译甚至没有发生。我的理论是,当我评估惰性对象时,gettext 正在翻译目录中寻找文字字符串““foo”等于“bar”(例如),而不是带有占位符和命名值的东西。

    考虑到这一点,我还尝试将整个 format() 包装在惰性对象中,如下所示:
    return _('“{key}” equals “{value}”'.format(key=self.key, value=self.value))
    

    但它似乎产生了零差异。 =/

    我现在可以使用 string_concat() ,但有时,占位符需要在某些翻译中移动,所以我想弄清楚这一点。

    我开始认为一个人根本不能将占位符与 gettext_lazy 一起使用。

    注意:我已查看 django: Translation with variables inside ,但是a)没有接受的答案,b)他使用的是gettext,而不是gettext_lazy。

    最佳答案

    好的,这里的解决方案是提供额外的惰性层(感谢 Django 核心开发人员:Florian Apolloner AKA “apollo13”)。

    这是我修改后的功能:

    from django.utils import six
    from django.utils.functional import lazy
    
    class MyModel(models.Model):
    
        key = models.CharField(...)
        value = models.CharField(...)
    
        @property
        def configuration_string(self):
    
            def wrapper():
                return _('“{key}” equals “{value}”').format(
                    key=self.key,
                    value=self.value
                )
    
            return lazy(
                wrapper,
                six.text_type
            )
    

    唯一的事情是,在我使用它的地方,我必须记得按如下方式评估包装器函数:
    from django.utils.encoding import force_text
    
    config = my_model_instance.configuration_string
    # NOTE: Evaluate the lazy function wrapper inside the force_text()
    config_str = force_text(config())
    

    现在,就我而言,我需要支持第 3 方开发人员编写函数 configuration_string 的情况。返回惰性函数包装器,惰性求值的翻译字符串或仅返回常规字符串,因此我使用:
    import types
    from django.utils.encoding import force_text
    from django.functional import Promise
    
    config = my_model_instance.configuration_string
    
    if isinstance(config, types.FunctionType):
        config_str = force_text(config())
    elif isinstance(config, Promise):
        config_str = force_text(config)
    else:
        config_str = config
    

    再次感谢 Apollo13 的指导!

    关于django - 如何返回带有占位符的惰性翻译对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24340527/

    相关文章:

    python - django.db.utils.IntegrityError : NOT NULL constraint failed: new__users_personal_detail. husband_adhaarcopy

    Django Rest Framework - 测试中的 AssertionError

    python - Django : select_related with ManyToManyField

    php - OSX 中的 xgettext 从 PHP 代码创建 .po 文件

    django - celery : Execute task after a specific time gap

    python - 使用 Django ORM 中多对一表中的值查询不同的模型实例

    python - 如何从滚动文本小部件中获取文本?

    perl - 我如何结合 Catalyst 和 ngettext?

    使用 Clang 编译并使用 GETTEXT

    python - Django Makemessages CommandError ASCII 编码