A Quick Guide to Django I18n
In this article, you'll learn how to easily do translation and localization in Django, the popular Python web framework. Read on!
Join the DZone community and get the full member experience.
Join For FreeLearn how to easily do translation and localization in Django, the popular Python web framework.
Translating your web application to different languages and adding proper localization is something we all should do! This tutorial will give you a short introduction on how to get started with the Django localization process. Part of this can be easily applied to general Python localization and we also show you how you can speed up your i18n workflow even more by using Phrase.
We assume, that you have a working Django application and that you have installed gettext (for example, via pip install gettext
). If you haven't used Django before, you may want to take a look at the official tutorial first and come back later.
Basic Setup
So let’s suppose you have a Django project called mysite
and an application called polls
. The structure of your project should look something like this:
/
manage.py
mysite/
__init__.py
settings.py
urls.py
wsgi.py
polls/
migrations/
__init__.py
admin.py
models.py
tests.py
views.py
The first step is to make sure that you have activated internationalization in your configuration. To do this, you have to make the following changes to mysite/settings.py
:
# mysite/settings.py
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
Internationalize Templates
Then you have to mark all strings which have to be translated. Suppose you have the following template file polls/templates/polls/index.html
<!-- polls/templates/polls/index.html -->
<h1>Welcome to our site!</h1>
<p>Here you find polls.</p>
This file needs to be adapted to look like this:
<!-- polls/templates/polls/index.html -->
{% load i18n %}
<h1>{% trans 'WelcomeHeading' %}</h1>
<p>{% trans 'WelcomeMessage' %}</p>
So we import the localization package and replace all texts with trans 'SomeTranslationKeyName'
. Alternatively, you can use the default translation text as the translation key. This way, you will always have a good default text, if there is no translation available for the particular key.
Internationalize Inside Python Code
When you want to localize strings within your Python code (for example inside polls/views.py
), you need to import the ugettext
function. It is normal to alias it to _
. So a simple localized view function would look like this
# polls/views.py
from django.http import HttpResponse
from django.utils.translation import ugettext as _
def index(request):
output = _('StatusMsg')
return HttpResponse(output)
Create Translation Files
Now we have to create the translation files for every locale we want to support. To do this, create the directory polls/locale
and inside the directory polls
run:
$ django-admin makemessage -l de
You can replace de
with the locale code of the language you'd like to add. In our example, this command will create the gettext file polls/locale/de/LC_MESSAGES/django.po
with the content:
# polls/locale/de/LC_MESSAGES/django.po
...
#: templates/polls/index.html:3
msgid "WelcomeHeading"
msgstr ""
#: templates/polls/index.html:4
msgid "WelcomeMessage"
msgstr ""
And you can fill in the translations:
# polls/locale/de/LC_MESSAGES/django.po
...
#: templates/polls/index.html:3
msgid "WelcomeHeading"
msgstr "Willkommen auf unserer Seite!"
#: templates/polls/index.html:4
msgid "WelcomeMessage"
msgstr "Hier findet Ihr Umfragen."
When you have finished translating, you have to compile everything by running the following:
$ django-admin compilemessages
Again, this is run inside the directory polls
.
To quickly check that your translations work, you have to change the language code inside mysite/settings.py
like so
# mysite/settings.py
LANGUAGE_CODE = 'de'
When you open the polls application inside the browser, it should now be translated to German.
Speed Up Your Process Using Phrase
If you are using Phrase to manage your translations, you actually don’t need to manually create and edit the *.po
files! You just have to create and translate the keys WelcomeHeading
and WelcomeMessage
within Phrase and use the export function to download your *.po
files.
If you have installed our command line tool, the Phrase Client, your workflow is even simpler. Just create a configuration file .phraseapp.yml
within your project’s root directory with the following content:
# .phraseapp.yml
phraseapp:
access_token: <your access token>
project_id: <your project's id on PhraseApp>
file_format: po
pull:
targets:
file: "polls/locale/<locale_code>/LC_MESSAGES/django.po
Then run the following in the root directory of your project:
$ phraseapp pull && django-admin compilemessages
This will update all translations in your project.
By the way, using our In-Context Editor within your Django application is also really simple! You only need to install django-phrase
with pip
:
$ pip install django-phrase
Then just change all the templates you'd like to use the In-Context-Editor on, in the following way:
<!-- polls/templates/polls/index.html -->
{% load i18n %}
{% load phrase_i18n %}
{% phrase_javascript %}
<h1>{% trans 'WelcomeHeading' %}</h1>
<p>{% trans 'WelcomeMessage' %}</p>
Note: it is important to load phrase_i18n
afteri18n
.
Finally, add the following lines to your configuration and you are ready to go!
# mysite/settings.py
PHRASE_ENABLED = True
PHRASE_PROJECT_ID = 'YOUR_PROJECT_ID'
PHRASE_PREFIX = '{{__'
PHRASE_SUFFIX = '__}}'
Select Locales
One usually wants to select the locale according to the user’s browser settings. In order to do this, you have to change the mysite/settings.py
file to the following
# mysite/settings.py
from django.utils.translation import ugettext_lazy as _
...
MIDDLEWARE_CLASSES = (
...,
'django.middleware.locale.LocaleMiddleware',
...,
)
...
LANGUAGE_CODE = 'en-us'
LANGUAGES = (
('en-us', _('English')),
('de', _('German')),
)
This way, if the user has Germany as their locale, they will see the de
translations. Otherwise, the default locale will be en-us
. You can check that this is working properly with curl:
$ curl http://localhost:8000/polls -H "Accept-Language: de"
This should return something like this:
<h1>Willkommen auf unserer Seite!</h1>
<p>Hier findet Ihr Umfragen.</p>
Further Reading
If you want to learn more about internationalization in Django, take a look at the official documentation. There is also another nice article.
If you want to learn more on how you can setup the Phrase In-Context-Editor within your Django application, take a look at the documentation at Phrase. You can also find the full sources of the demo application we used in this tutorial on GitHub.
Also, if you are using Flask, we have another blog post introducing you to localization in this framework.
Opinions expressed by DZone contributors are their own.
Comments