Django翻译选择字段

时间:2017-04-09 09:59:28

标签: python django translation

我有一些这样的模型:

class Payment(models.Model):
    class Status(IntEnum):
        open = 0
        balance = 2
        closed = 1
    status = models.IntegerField(choices=enum_to_choices(Status), default=0, verbose_name=_("Status"))

我使用枚举来表示我的选择,并在我的应用程序的其他部分使用它们。我将这些转换为元组,以便在选择字段中使用以下代码:

from django.utils.translation import ugettext_lazy as _
def enum_to_choices(enum):
    x = tuple([(x.value, _(x.name.replace("_", " "))) for x in enum])
    return x

代码的转换部分有效,我可以使用这些字段作为选择,但翻译不起作用,它不会显示在我的翻译文件中。 如果我使用像"open"之类的静态字符串将参数更改为uggettext_lazy,它会显示出来。

这里发生了什么?

1 个答案:

答案 0 :(得分:1)

在我看来,这与makemessages命令有关,该命令由于某种原因与非静态字符串斗争。

我无法详细说明原因,但这里有解决问题的方法:

您实际上必须在翻译文件中手动创建字符串  (django.po):

#: .\polls\models.py:enum_to_choices

msgid "open"
msgstr "ouvert"

msgid "closed"
msgstr "fermé"

msgid "balance"
msgstr "solde"

不要忘记django-admin compilemessages,并且应该出现已翻译的字符串!
这不是理想的,特别是对于长枚举,但总比没有好。

如果有人知道makemessages(及其使用的xgettext程序)的内部运作方式并有解释,请告诉我们^^

其他解决方案:使用推荐的选择结构

另一种解决方案是,如果您不是绝对需要选择在枚举中,则使用选择结构as shown in the documentation

from django.utils.translation import ugettext_lazy as _

class Payment(models.Model):
    OPEN = 0
    CLOSED = 1
    BALANCE = 2
    STATUS_CHOICES = (
        (OPEN, _('open')),
        (CLOSED, _('closed')),
        (BALANCE, _('balance')),
    )
    status = models.IntegerField(choices=STATUS_CHOICES, default=OPEN, verbose_name=_("Status"))

然后在django-admin makemessages上,字符串将被添加到翻译文件中。

您可以轻松获得选择的价值,就像使用枚举一样:

from .models import Payment
new_payment = Payment.objects.create(status=Payment.OPEN)