Django translations: Quick Guide

Today, 4th December 2022, Ukraine is still bravely fighting for democratic values, human rights and peace in whole world. Russians ruthlessly kill all civilians in Ukraine including childs and destroy their cities. We are uniting against Putin’s invasion and violence, in support of the people in Ukraine. You can help by donating to Ukrainian's army.

This is a short hint which is a smaller version of Django Translation Documentation

Step 1 – Setup

Make sure in you have the next settings:

USE_I18N = True
USE_L10N = True
os.path.join(os.path.dirname(__file__), "..", "locale"), # folder where locale files will sit

Step 2 – Prepare HTML templates

In all your templates (.html files) make sure you load i18n at the beginning of each file:

{% load i18n %}

Wrap all English text strings which are visualized into trans. E.g. if you had

<div class="item">Go Home</div>

It should become:

<div class="item">{% trans "Go Home" %}</div>

Step 3 – Prepare Python strings code

If somehow it happened that your strings located in python view files e.g. (it happens πŸ˜‰) then add import to the files:

from django.utils.translation import gettext as _

And wrap text strings into:

category = {
'item': _('Red Snakes'),
Better do it on top level of each view function, within dict or using several local variables. Gettext which used under the hook is pretty taugh to find it inside of some nested operators...

Step 4 – Generate text .po file for translators

Use the command to collect all text strings into .po file which will appear in locales folder (designed on step 1):

pipenv run django-admin makemessages -l ja

The commands generate files for one language. For several languages generate it multiple times with different -l argument.

Step 5 – Translate .po file

Basically, you need to type in an empty untranslated string under their English version to the target language

You might want to do it:

The last one could be a pretty interesting option to faster fulfill the translation for cheaper proofreaders.

Basically, after following the installation guide you could:

pipenv run python translate_messages --untranslated

And it will populate .po file using a translator of the Google Company.

However, you might easily connect to another service like Deepl:

AUTOTRANSLATE_TRANSLATOR_SERVICE = 'apps.yourapp.utils.DeeplTranslatorService'

The code of Service:

class DeeplTranslatorService(BaseTranslatorService):
def __init__(self):
def translate_string(self, text, target_language, source_language='en', handle_xml=False):
print('[INFO][PAID] Doing deepl request')
conf = {
'auth_key': settings.DEEPL_TOKEN,
'text': text,
'source_lang': source_language.upper(),
'target_lang': target_language.upper(),
if handle_xml:
conf['tag_handling'] = 'xml'
resp = requests.get(self.BASE_URL, data = conf)
print("TRANSLATION", resp.text, resp.status_code)
text = json.loads(resp.text)['translations'][0]['text']
return text
def translate_strings(self, strings, target_language, source_language='en', optimized=True):
result = []
for s in strings:
text = self.translate_string(s, target_language, source_language)
return tuple(result)

Step 5 – Compile .po into binary .mo used by Django

pipenv run django-admin compilemessages

Step 6 – Activate the translation somehow

There are lot's of internal Django toolings to activate translations. For example by using sub-folder-based URLs parser like or subdomain-based like Or depending on user's browser preference.

Here I will share the most flexible custom way.

Just create middleware and depending on any info from request (hostname/url/Geolocated IP) we can just call one function:

from django.utils.translation import activate

Image for a hint

Ivan Borshchov profile picture
Jun 04, 2021
by Ivan Borshchov
Did it help you?
Yes !

The link for the translations documantation is wrong.