Django ugettext_lazy,interpolation和ChoiceField

dgi*_*rdi 7 django internationalization

我希望ChoiceField有这些选择:

choices = [(1, '1 thing'),
           (2, '2 things'),
           (3, '3 things'),
           ...]
Run Code Online (Sandbox Code Playgroud)

我希望翻译它.

这不起作用:

choices = [(i, ungettext_lazy('%s thing', '%s things', i) % i) for i in range(1,4)]
Run Code Online (Sandbox Code Playgroud)

因为只要插入了惰性对象,它就会变成一个unicode对象 - 因为在启动时会评估ChoiceField.choices,它的选择将在Django启动期间处于活动状态.

我可以使用ugettext_lazy('%s things' % i),但这需要翻译每个数字,这是愚蠢的.这样做的正确方法是什么?

Jim*_*unt 5

在 Django 文档TranslationWorking with lazy translation objects 中,我看到一条评论似乎解决了您的问题。

在模型和实用函数中使用ugettext_lazy()ungettext_lazy()标记字符串是一种常见的操作。当您在代码的其他地方使用这些对象时,您应该确保不会意外地将它们转换为字符串,因为它们应该尽可能晚地转换(以便正确的区域设置生效)。这需要使用下面描述的辅助函数。

然后它们出现django.utils.functional.lazy(func, *resultclasses)django.utils.functional模块文档目前没有涵盖。但是,根据django.utils.functional.py源代码,它“将任何可调用对象转换为惰性求值的可调用对象......该函数在每次访问时都会被求值”。

延迟翻译中延迟翻译的其他用途中修改他们的示例以合并您的代码,以下代码可能适合您。

from django.utils import six  # Python 3 compatibility
from django.utils.functional import lazy
from django.utils.safestring import mark_safe

choices = [
    (i, lazy(
        mark_safe(ungettext_lazy('%s thing', '%s things', i) % i),
        six.text_type
    )# lazy()
    for i in range(1,4)
]
Run Code Online (Sandbox Code Playgroud)

此外,django.utils.functional模块文档确实提到了函数装饰器allow_lazy(func, *resultclasses)。这使您可以编写自己的函数,该函数将惰性字符串作为参数。“它修改了函数,以便如果使用延迟翻译作为第一个参数调用它,则函数评估会延迟,直到需要将其转换为字符串。” lazy(func, *resultclasses)不是装饰器,它修改了一个可调用对象。

注意我还没有在 Django 中尝试过这段代码。我只是传递我在文档中找到的内容。希望它会指向你可以使用的东西。