Django Translations Working example

giorgi beria
Analytics Vidhya
Published in
4 min readJan 28, 2020

I work as a back-end developer in one of the biggest companies in Batumi city Georgia.

recently at work, I have been asked to make translations available in my Django app. We expect users to read these 3 languages: Georgian, Russian, English.
I will write a guide that will help you set it up. Feel free to add more languages.
1) The first step in setting up is to import gettext_lazy in
from Django.utils.translation import gettext_lazy as _

we will be using “_”(underscore) character to mark translatable strings.

2) Next thing we will do is import Django localisation middleware called LocaleMiddleware. Make sure you follow this order, because localemiddleware uses sessionmiddleware and same about CommonMiddleware.

Django developers call this process an activation of translations

3) Now we will add some variables in settings file to let Django know which languages we will be using

('ka', _('Georgian')),
('ru', _('Russian')),
('en', _('English')),



Languages list contains sets of language code and Its name divided by “,”(comma).
Language_code variable contains preferred language code. Finally, we add Locale_paths which is folder inside our app created by django-admin startapp.

4) Make sure you create this folder structure under app’s directory.

folder structure

This way Django will know where to place generated .po files for each language
PO file is a portable object file, which is text-based. These types of files are used in common in software development. The . PO file may be referenced by Java programs, GNU gettext, or other software programs as a properties file.
Django uses gettext to interact with translation PO and mo files.

5) After these steps we will prepare our files for translation. I will show one endpoint

def hello_world(request):
response_data = {'msg': _('This Url does not exist. Check spelling.')}
return HttpResponse(response_data)

As you may have noticed there is _(‘This Url does not exist. Check spelling.’)
This string is prepared for translation.
To make it work we must generate translation files using Django-admin makemessages command .


Django created .po files for every language.

.po files

Let’s open Georgian one.

# This file is distributed under the same license as the PACKAGE package.
#, fuzzy
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-01-28 14:45+0400\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"

"This Url does not exist. Check spelling"
msgstr ""

"Please add your authorisation token in header"
msgstr ""

as you see Django found some translation ready strings and placed here in .po file.

msgid here is the how we request msgstr — Actual translated string.

make sure you remove #, fuzzy (7-th) line from every .po file
What “fuzzy” means is that a django application is in process of adding support for second language.
now translators can place translated strings in msgstr line of each string.
In Georgian it would be “ეს URL არ არსებობს. შეამოწმეთ მართლწერა”

"This Url does not exist. Check spelling"
msgstr "ეს URL არ არსებობს. შეამოწმეთ მართლწერა"

6) Now we can compile translations using django-admin compilemessages.

django-admin compilemessages

django created .mo files which he uses to get translated strings.
MO files: MO, or Machine Object is a binary data file that contains object data referenced by a program. It is typically used to translate program code, and may be loaded or imported into the GNU gettext program.

created files

Lastly lets make request and ask for Georgian strings. We must add
Accept-language header in request headers.

here you go

Thanks for reading. Share some new staff with me also. :D
Join my Telegram Group to discuss some awesome staff