Django locale message bundles

In the previous section Django language selection workflow you used the Django admin to experiment how to visualize Django pages in different languages. The source of these different language translations is in Django's built-in locale message bundles.

Locale message bundles are text files that consist of translation message ids and the corresponding translated text for the id in a given language. Although it's technically possible to manually build locale message bundles, locale message bundles are either built-in to Django or automatically created, the latter by searching a Django project's source code for translation message ids.

In listing 13-4, you can see the LANGUAGES variable in settings.py file uses four different translation message ids – 'Spanish', 'English', 'French' and 'German' – defined through the django.utils.translation.gettext_lazy method that uses the _ syntax convention.

As it turns out, these four translation message ids are already provided as part of the Django distribution itself (i.e. you don't need to create translations for them). The Django distribution includes locale message bundles for over ten built-in packages (e.g. configuration [conf package], the Django admin [contrib.admin package], user authentication [contrib.auth package]) and with support for close to one-hundred languages, this means there are over one-thousand locale message bundles in the Django distribution.

Locale message bundles structure and location

Locale message bundles follow certain conventions which are illustrated in listing 13-5.

Listing 13-5. Django local message bundle structure and location

+-<app_package>-+
                +-locale-+ 
                         +-es-+
                         |    +-formats.py
                         |    |
                         |    +-LC_MESSAGES-+
                         |                  +-django.mo
                         |                  +-django.po
                         |
                         +-en_GB-+
                                 +-formats.py
                                 |
                                 +-LC_MESSAGES-+
                                               +-django.mo
                                               +-django.po

First in listing 13-5 notice inside an app's main package is a directory called locale. Next, inside the locale directory are sub-directories for all the language bundle types supported by the app. Notice the language sub-directories in listing 13-5 follow a similar syntax to the LANGUAGE_CODE & LANGUAGES values from past sections.

Individual language directories also use two lower case letters (e.g. es, fr) which is identical to LANGUAGE_CODE values, but language+country combinations vary from the "two lower case letter language, dash, two lower case letter country" (e.g. en-gb, pt-br) used in LANGUAGE_CODE values to a "two lower case letter language, underscore, upper case letter country" syntax (e.g. en_GB, pt_BR). This last variation is particularly important when you create your own locale message bundles, but more one this shortly.

Next, inside each language directory is an optional formats.py file with formatting configurations for each language (e.g. dates & numbers) -- note the formats.py file is intended to be defined once per project, but more on this in the section on date and number formatting.

Inside each language directory is the LC_MESSAGES directory which contains two files:

With this overview of locale message bundles structure and location, let's explore the locale message bundles for the translation message keys in listing 13-4.

Go to your Python installation directory (e.g. /python/coffeehouse/lib/python3.8/site-packages) and then go to the django/conf/locale/ sub-directory in it, inside this last directory you'll see all the languages supported by the django.conf package. Open the django.po file inside the es/LC_MESSAGES/, en/LC_MESSAGES, fr/LC_MESSAGES and de/LC_MESSAGES directories and you'll see statements like the ones listing 13-6:

Listing 13-6. Django local message bundles for django.conf package.

----------------------------------------------------------------------------
# Definitions in es/LC_MESSAGES/django.po

msgid "Spanish"
msgstr "Español"

msgid "English"
msgstr "Inglés"

----------------------------------------------------------------------------
# Definitions in en/LC_MESSAGES/django.po

msgid "Spanish"
msgstr ""

msgid "English"
msgstr ""

----------------------------------------------------------------------------
# Definitions in fr/LC_MESSAGES/django.po

msgid "Spanish"
msgstr "Espagnol"

msgid "English"
msgstr "Anglais"

----------------------------------------------------------------------------
# Definitions in de/LC_MESSAGES/django.po

msgid "Spanish"
msgstr "Spanisch"

msgid "English"
msgstr "Englisch"

The msgid values correspond to the translation message ids and the msgstr is the translated text of the key (e.g. for the es language bundle you can the translations are in Spanish). If you inspect django.po files for other language directories, you'll notice the msgid values remains the same, but the msgstr is translated into the language directory its in.

Custom project locale message bundles