Django translating choice fields

孤街浪徒 提交于 2019-12-12 04:19:58

问题


I've got some models like this:

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"))

I'm using a enum to denote my choices and to use them throughout other parts of my application. I'm converting these to tuples to use in choice fields with the following code:

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

The conversion part of the code works, i can use these fields as choices but the translation doesn't work, it doesn't show up in my translation files. If i change the parameter to uggettext_lazy with a static string like "open" it does show up.

What's going on here?


回答1:


It seems to me that this is related to the makemessages command, which for some reason struggles with non-static strings.

I couldn't elaborate on the why, but here's how you can solve the problem:

You actually have to manually create the strings in the translation files (django.po):

#: .\polls\models.py:enum_to_choices

msgid "open"
msgstr "ouvert"

msgid "closed"
msgstr "fermé"

msgid "balance"
msgstr "solde"

Don't forget to django-admin compilemessages, and translated strings should appear!
This is not ideal, especially for long enums, but better than nothing.

If someone here knows the inner workings of makemessages (and the xgettext program it uses) and has an explanation, please let us know ^^


Other solution: use recommended choices structure

Another solution, if you don't absolutely need the choices to be in enums, is using the choices structure 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"))

And then on django-admin makemessages the strings will be added to the translation files.

You can easily get the value of a choice, as you would with an enum :

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


来源:https://stackoverflow.com/questions/43305400/django-translating-choice-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!