Practical guide to internationalize a Django app in 5 steps.
An easy workflow to understand basic steps
Overview
Making an app available in different languages can be a daunting task
in Django, because it uses some external resources (e.g.:gettext
)
that you need to be familiar with, before doing it.
This is a guide put emphasis in the steps required to translate an app, to understand the process of translating strings works in Django at a higher level.
For a detailed explanation of each step, please check the official documentation at: https://docs.djangoproject.com/en/dev/topics/i18n/translation/
Basically, Django expects to find files containing translation for
each language (message files with a .po
file extension).
These files are generated with a command and needs to be updated after you change some of the translation keys in your code.
Workflow
1. Translate strings
1.1 Translations in code
Translate all your desired strings in your Python code, for example a
description
in an view:
from django.views.generic.base import TemplateView
from django.utils.translation import gettext as _
class HomePageView(TemplateView):
template_name = "games/home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['description'] = _("description")
These are known as: translation strings.
1.2 Translations in templates
Translations in templates requires to load i18n
and
use the translate
templatetag.
e.g.: in a site-wide template templates/base.html
:
{% load i18n %}
<html>
<head>
{% translate "This is my title" as my_title %}
<title>{% block title %}{{my_title}}{% endblock %}</title>
...
</head>
...
2. Set up paths for translations
Create a locale
directory in each app, where each language file will
reside.
This directory can be at your project root level /
or inside each
app where are translations.
2.1 Add the base translate directory
If you use translation in apps registered in the INSTALLED_APPS
setting, you can skip this step.
When you have a /locale
directory at your root you will have to
specify it in Django’s settings.py
file with the LOCALES_PATH
variable like:
LOCALE_PATHS = [os.path.join(BASE_DIR, 'locale'),]
If you skip this step, the template tags at your
/templates/base.html
for example will compile but won’t detect any
other language.
3. Create message files
Use the command makemessages
to create the translation files (django.po
):
Runs over the entire source tree of the current directory and pulls out all strings marked for translation. It creates (or updates) a message file in the conf/locale (in the django tree) or locale (for projects and applications) directory. You must run this command with one of either the –locale, –exclude, or –all options.
We create a translation file for Spanish: ./manage.py makemessages --locale es
.
$ ./manage.py makemessages --locale es
processing locale es
They would look like: $APPPATH/locale/<language>/LC_MESSAGES/django.po
or like /locale/<language>/LC_MESSAGES/django.po
at root level.
For example, with an app called games
, the tree structure after
the command is run will look similar to:
.
βββ db.sqlite3
βββ games
βΒ Β βββ admin.py
βΒ Β βββ apps.py
βΒ Β βββ __init__.py
βΒ Β βββ locale
βΒ Β βΒ Β βββ es
βΒ Β βΒ Β βββ LC_MESSAGES
βΒ Β βΒ Β βββ django.po
βββ locale
βββ es
βββ LC_MESSAGES
βββ django.po
And each file looking like:
/locale/es/LC_MESSAGES/django.po
:
#: games/views.py:14
msgid "This is my description"
msgstr ""
Any translation not in games
app, like for example a template at
root directory at templates/base.html
, would appear at base:
/locale/es/LC_MESSAGES/django.po
#: templates/base.html:6
msgid "This is my title"
msgstr ""
4. Translate the strings
Go to each django.po
file and translate put the translation of
msgid
into msgstr
.
For example: /locale/es/LC_MESSAGES/django.po
:
#: games/views.py:14
msgid "This is my description"
msgstr "Esta es mi descripciΓ³n"
5. Compile translations
To make it possible for Django to understand each translation, we
compile them with ./manage.py compilemessages
.
Compiles .po files created by makemessages to .mo files for use with the built-in gettext support
$ ./manage.py compilemessages
processing file django.po in /locale/es/LC_MESSAGES
processing file django.po in /games/locale/es/LC_MESSAGES
Extras
Test
To test it works you can change the default language of the website
in settings.py
using: LANGUAGE_CODE = 'es'
and running the local
server.
Update
Every time you modify or create a new translation string, you will have to run again:
- makemessages (if adding or moving translation strings)
- compilemessages (when some translation changes)
References
- Django manual pages
- i18n docs https://docs.djangoproject.com/en/dev/topics/i18n/translation/#how-django-discovers-translations
- https://docs.djangoproject.com/en/3.1/ref/django-admin/#django-admin-makemessages
- August 1, 2023
- How to create a reusable Django app and distribute it with PIP or publish to pypi.orgJune 29, 2021
- How To Serve Multiple Django Applications with uWSGI and Nginx in Ubuntu 20.04October 26, 2020
- How to add favicon to Django in 4 stepsSeptember 3, 2020
- Categories in Django with BreadcrumbsAugust 30, 2020
- How To Migrate From SQLite To PostgreSQL In Django In 3 stepsAugust 28, 2020
- Practical guide to internationalize a Django app in 5 steps.
- Disable new users singup when using Django's allauth packageSeptember 3, 2019
- How to add ads.txt to Django as requested by Google AdsenseAugust 30, 2019
- Have multiple submit buttons for the same Django formJuly 2, 2019
- Better Testing with Page Object Design in DjangoMay 1, 2019
- Generating slugs automatically in Django without packages - Two easy and solid approachesFebruary 14, 2019
- How to set up Django tests to use a free PostgreSQL database in HerokuFebruary 13, 2019
- Dynamically adding forms to a Django FormSet with an add button using jQueryFebruary 6, 2019
- Use of Django's static templatetag in css file to set a background imageFebruary 1, 2019
- Activate Django's manage.py commands completion in Bash in 2 stepsJanuary 29, 2019
- Sending Emails with Django using SendGrid in 3 easy stepsJanuary 9, 2019
- Adding Users to Your Django Project With A Custom User ModelSeptember 21, 2018
- Setting Up A Factory For One To Many Relationships In FactoryboyApril 17, 2018
- Generate UML class diagrams from django modelsMarch 24, 2018
- Set Up Ubuntu To Serve A Django Website Step By StepJuly 3, 2017
- Django Project Directory StructureJuly 16, 2016
- How to Have Different Django Settings for Development and Production, and environment isolationJune 10, 2016
- Django OverviewJune 2, 2016
Django Forms
- Adding a Cancel button in Django class-based views, editing views and formsJuly 15, 2019
- Using Django Model Primary Key in Custom Forms THE RIGHT WAYJuly 13, 2019
- Django formset handling with class based views, custom errors and validationJuly 4, 2019
- How To Use Bootstrap 4 In Django FormsMay 25, 2018
- Understanding Django FormsApril 30, 2018
- How To Create A Form In DjangoJuly 29, 2016
Articles
Subcategories
Except as otherwise noted, the content of this page is licensed under CC BY-NC-ND 4.0 . Terms and Policy.
Powered by SimpleIT Hugo Theme
·