Django I18N on Windows

django, i18n, programming

Concise run book on I18N to get things started

Prerequisite

Know the difference between locale name and language name:

  • Locale name: <language code>_<COUNTRY CODE> (examples: “en_US“, “fr_CA“), case sensitive.
  • Language name: <language subtag>-<range subtag> (examples: “en-us“, “fr-ca“), case insensitive.

They usually look alike EXCEPT locale names use the underscore (“_”) character to separate the language and country while the language names use the dash (“-“) to separate the subtags.

Creating a .po file for translation

  • Install the prerequisite gettext library. See gettext on Windows.
  • Create a “locale” subdirectory in the project’s base directory1.
  • Run python manage.py makemessages -l <locale name> [-l <locale name> ...] and provide locale names
    E.g.
    python manage.py makemessages -l en_US -l fr_CA

Translate each .po file

This can be done manually by editing the *.po file and fill in the msgstr values or by sending the file to a translation service.

Compile the translated .po file

  • Run python manage.py compilemessages
  • This will produce a .mo (e.g. django.mo) file next to the .po (e.g. django.po) file

Configure the Django settings file

Adding the LocaleMiddleware

Adding the middleware “django.middleware.locale.LocaleMiddleware” in the list MIDDLEWARE.

IMPORTANT: it must follow “django.contrib.sessions.middleware.SessionMiddleware” and precede “django.middleware.common.CommonMiddleware“.

For example:

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.locale.LocaleMiddleware',  # Order is important
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

Set the languages supported

Add/edit the setting LANGUAGES, listing all the languages supported. The value should be a list of tuples (language name, description). For example:

LANGUAGES = [
    ('en', 'English'),
    ('es-419', 'Spanish Latin America'),  # NOTE: language name, not locale name
]

Set the path(s) to locale subdirs

Add the path to the “locale” subdirectory where the *.mo files can be found. For example:

LOCALE_PATHS = [
    BASE_DIR / "locale",
]

  1. NOTE that it is also possible to create additionallocale” subdirs under individual apps’ subdirs, as long as they are configured in setting’s LOCALE_PATHS.