如何使用占位符返回延迟翻译对象?

时间:2014-06-21 10:08:06

标签: django gettext

在我在Python v2.7.x上运行的Django v1.6.5项目中,我有一个Model,它将其配置作为字符串返回。我需要返回的字符串是一个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')

在这些情况下,这似乎工作正常:

  1. 静态字符串:(见上文) - 有效!
  2. 字符串连接:return string_concat(self.key, _(' equals '), self.value) - 有效!
  3. 什么是正在使用gettext_lazy和占位符,la:

    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字符串,其中占位符填充为E.g.,'“foo”等于“bar”'。注意,即使第一个调用上下文是FR(例如),我也会得到一个EN字符串。这告诉我,翻译甚至都没有发生。我的理论是,当我评估惰性对象时,gettext正在翻译目录中寻找文字字符串“”foo“等于”bar“”(例如),而不是具有占位符和命名值的字符串。

    考虑到这一点,我也尝试将整个格式()包装在惰性对象中,如下所示:

    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。

2 个答案:

答案 0 :(得分:2)

好的,这里的解决方案是提供额外的懒惰层(谢谢,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())

现在,在我的情况下,我需要支持第三方开发人员编写函数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的指导!

答案 1 :(得分:0)

我遇到了一个非常类似的问题,发现自Django 1.11以来,使用gettext_noop而不是gettext_lazy可以使用。