[Django]-Django internationalization for admin pages – translate model name and attributes

49👍

Important things not mentioned in the Django documentation:

  • run django-admin compilemessages, e.g. as a part of your build
    process. Thanks stevejalim!
  • apply django’s ugettext_lazy() to model names ( Meta class and verbose_name )
  • attribute (model field verbose_name) names can also be translated with ugettext_lazy()
  • use lazy translation in your model metadata, otherwise the translation
    happens while loading the model classes and the settings of your users,
    especially the browser settings, will not be taken into account
  • I use some scoping for attribute names, e.g. separating the model name
    and attribute names with a pipe. The same convention is used in
    ruby-gettext. Background: attribute names like ‘title’ or ‘name’ translated
    differently in the most languages depending on context. Example
    ‘Book|title’ -> ‘Titel’ or ‘Buchtitel’ in German. But
    ‘Chapter|title’ would be translated as ‘Überschrift’.

Example using above principles:

from django.utils.translation import ugettext_lazy as _
class Order(models.Model):
    subject = models.CharField(max_length=150, verbose_name = _('Order|subject'))
    description = models.TextField(            verbose_name = _('Order|description'))
    class Meta:
        verbose_name = _('order')
        verbose_name_plural = _('orders')

Or is there a better way to translate the model and admin pages?

Either way we should enhance the Django documentation and fill the gap!

👤geekQ

2👍

See https://automationpanda.com/2018/04/21/django-admin-translations/
It’s author made an excellent work in showing how to master all django translation features step by step. It’s much better than oficial documentation to me.

1👍

I also couldn’t translate a model label in Django Admin because there are #, fuzzy in django.po as shown below:

# "django.po"

...

#: .\my_app1\models.py:12
#, fuzzy # <- Here
msgid "person"
msgstr "personne"

#: .\my_app1\models.py:13
#, fuzzy # <- Here
msgid "persons"
msgstr "personnes"

...

So, I removed #, fuzzy from django.po as shown below, then I could translate the model label in Django Admin. *You can see my question and my answer explaining it in detail:

# "django.po"

...

#: .\my_app1\models.py:12
msgid "person"
msgstr "personne"

#: .\my_app1\models.py:13
msgid "persons"
msgstr "personnes"

...

In addition, fuzzy is explained in the doc as shown below:

fuzzy

This flag can be generated by the msgmerge program or it can be inserted by the translator herself. It shows that the msgstr string might not be a correct translation (anymore). Only the translator can judge if the translation requires further modification, or is acceptable as is. Once satisfied with the translation, she then removes this fuzzy attribute. The msgmerge program inserts this when it combined the msgid and msgstr entries after fuzzy search only. See Fuzzy Entries.

0👍

I use both ugettext with _ and ugettext_lazy with a double __. Consequently, the makemessages management command was only collecting the first ones.

To collect both _ and __ we can ask the gettext tool to collect more than the default strings enclosed in _( ). To do this, we override the makemessages command: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#customizing-the-makemessages-command

# myapp/management/commands/makemessages.py
from django.core.management.commands import makemessages

class Command(makemessages.Command):
    self.stdout.write("----> Using our custom makemessages command to collect both _ and double __")
    xgettext_options = makemessages.Command.xgettext_options + ['--keyword=__']  # <-- added __

My models in Admin are now finally fully translated.

Leave a comment