Django i18n: Common causes for translations not appearing

I was having this problem with my project right now. I had the variable LANGUAGES on settings.py set this way:

LANGUAGES = (
('en', _('English')),
('pt-br', _('Brazilian Portuguese')),
)

And a folder structure with a locale folder, and a subfolder pt-br inside. Turns out that my translations weren't loading. The LANGUAGES variable follows the pt-br pattern, and the folders must be on pt_BR pattern. At least that's the only way it's working here!


Just got hit by one. I had the locale/ directory in the root of my project, but by default Django looks for translations in the INSTALLED_APPS directories, and in the default translations. So it didn't find the translations I added. But some of my strings were in the default translations that come with Django (eg "Search") so a few strings were translated, which confused me.

To add the directory where my translations were to the list of places that Django will look for translations, I had to set the LOCALE_PATHS setting. So in my case, where the locale/ directory and settings.py were both in the root of the django project I could put the following in settings.py:

from os import path
LOCALE_PATHS = (
    path.join(path.abspath(path.dirname(__file__)), 'locale'),
)

I'm trying to provide a complete check list:

  • In settings.py, are USE_I18N, USE_L10N, LANGUAGE_CODE, and LOCALE_PATHS set properly?

    • See this list for all allowed values of language identifiers. Note that Simplified Chinese is specified by zh-hans, not zh-cn.
  • In settings.py, is django.middleware.locale.LocaleMiddleware included in MIDDLEWARE in correct order?

  • Have you (re)run django-admin makemessages -l <locale-name> with the correct local name, from the correct place?

    • You can see an incomplete list of allowed locale name by running ls your/path/to/python/site-packages/django/conf/locale/ on your machine, or by taking a look at the source code
    • Note that you have to use _ rather than - here. For example, to specify simplified Chinese, execute django-admin makemessages -l zh_Hans, not zh_CN or zh_hans or zh-Hans or anything else.
  • Have you removed all fuzzy tags in your PO file(s)?

  • Have you (re)compiled the OP file(s) with django-admin compilemessages?

  • Have you restarted the web server?

Additional notes:

  • If some of your translation is overridden by Django's default translation, use contextual markers to bypass it. For example,

models.py

first_name = models.CharField(
    pgettext_lazy('override default', 'first name'),
    max_length=30
)

last_name = models.CharField(
    pgettext_lazy('override default', 'last name'),
    max_length=150
)

django.po

#: models.py:51
msgctxt "override default"
msgid "first name"
msgstr "姓"

#: models.py:55
msgctxt "override default"
msgid "last name"
msgstr "名"

and you'll see , instead of the default 姓氏, 名字.


Maybe the translated strings are marked as fuzzy?