PythonSnippets.Dev
A curated list of good to know Python Snippets. Visit PythonSnippets.dev.
Advertise with us
django translation   0   54389
Multiple language support in Django application: Internationalization in Django

Django has inbuilt support for translation. To add support of multiple languages in Django follow these steps.

Let's assume we are going to support English and Japanese in a Django application.


1. In the settings.py file make the below changes


1.1. Import the gettext_lazy function.

from django.utils.translation import gettext_lazy as _


1.2. define a list of tuples. The first item in the tuple will be language code and the second item will be the language label.

LANGUAGES = [
('en', _('English')),
('ja', _('Japanese')),
]


1.3. Internationalization and translation settings should be True

USE_I18N = True
USE_L10N = True


1.4. Add language session key and language cookie key. These keys are used to store language code in session and in cookies.

LANGUAGE_SESSION_KEY = 'session_language_appname'
LANGUAGE_COOKIE_NAME = 'cookie_language_appname' # it could be anything


1.5. Add LocaleMiddleware in the list of middlewares. It should be after SessionMiddleware and before CommonMiddleware. 

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


1.6. Now create a directory 'locale' in your app folder and add the path to the LOCALE_PATHS in the settings.py file. This is the list of paths where Django will look the translation files. Here we are creating a separate locale directory for each application.

LOCALE_PATHS = [
os.path.join(BASE_DIR, 'app_name/locale')
]




2. Translating static strings or labels in the template.


2.1. In each template where you want to translate the labels or strings, import the i18n template tag at the top of the page.

{% load i18n %}


2.2. Now use the trans template tag with the labels on page. For example on the login page, to translate the 'password' label as per active language, do this

{% trans 'password' %}


2.3. Now go inside the app directory and run the below command to generate the message translation file.

django-admin makemessages -l ja

Here -l flag is used to mention language. 'ja' is for Japanese. This will generate a file at the below path.

app_name/locale/ja/LC_MESSAGES/django.po


2.4. Open and edit the django.po file. You will find multiple records in the combination of 'msgid' and 'msgstr'. msgid is the default string label that needs to be converted. msgstr is the converted string. You will see one entry with 'msgid' equals to 'password' and 'msgstr' as an empty string. Find the Japanese translation of 'password' and put it against 'msgstr'. Repeat this process for all English strings.

#: templates/app_name/login.html:26
msgid "password"
msgstr "パスワード"


2.5. Now compile these messages by running the below command.

django-admin compilemessages

This will generate another file of compiled messages with the name django.mo at the same location and is not in a human-readable format.



3. Activating the second language in the Django application.


3.1 Django uses its own mechanism to discover the activated language. As you can see the last fallback is the LANGUAGE_CODE in the settings.py file. Change its value to 'ja' and reload the application. You will see all the labels in templates inside the trans template tag has been converted. If it is not working as expected, please check if the Japanese equivalent of a string is present in django.po file.



4. Providing an option to the user to set the prefered language in the application.


4.1. Option 3.1 is good for development and testing only. Every user should be able to set their own prefered language in the application. For this, we have to provide an option to selected the prefered language on the website.  In the header (or any page) of your application write the below code to display the option to set the prefered language.

{% get_available_languages as LANGUAGES %}
{% for lang in LANGUAGES %}
{% if LANGUAGE_CODE == lang.0 %}
{{lang.1}} ({{lang.0}})
{% else %}
<a href="{% url 'app_name:set_language' %}?l={{lang.0}}">{{lang.1}} ({{lang.0}})</a>
{% endif %} |
{% endfor %}


This code is listing all the available languages by picking the list of tuples from settings.py file. Currently, active language is not clickable. We can set the other language as the prefered language by clicking on it.


4.2. Create an entry in the urls.py file.

urlpatterns += [
path(r'set-language/', views.set_language, name='set_language'),
]


4.3. Create a view with the name set_language.

@login_required
def set_language(request):
lang = request.GET.get('l', 'en')
request.session[settings.LANGUAGE_SESSION_KEY] = lang
# return to previous view
response = HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
# set cookies as well
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang)
return response

This view is setting the selected language in session and then in cookies. After the view is redirecting to the same page we were on.


4.4 Reload the application and you can select the prefered language from the header of the application. The page will reload and your pages will have the text displayed in the prefered language.



5. Translating the text or messages returned from views.


5.1. In your views.py file, import the gettext_lazy file.

from django.utils.translation import gettext as _


5.2. Wrap the text inside gettext or gettext_lazy function (which has been imported under an alias _ )

msg = _('No entry in table')


5.3. Again repeat steps 2.3, 2.4 and 2.5.



6. Translating the Django admin site.


Built-in Django models, their field labels and common buttons in the admin site are automatically taken care of. 

6.1. To translate the user-defined models' names, use the verbose name of models.

class Meta:
managed = False
db_table = 'Person'
verbose_name = _('Person')
verbose_name_plural = _('Persons')


6.2. For field names, use help_text and verbose_name.

code = models.CharField(db_column='Code', primary_key=True, max_length=100,
help_text=_('Code'), verbose_name=_('Code'))
name = models.CharField(db_column='Name', max_length=500, help_text=_('Name'),
verbose_name=_('Name'))


For more points regarding admin-site, visit this article.



7. Translating messages returned by Javascript functions.


Everyone uses some or more javascript (or any framework of javascript) to do some basic validations at least. How to translate the messages returned by javascript functions.


7.1. Django have something called JavascriptCatalog which produces a javascript code with functions that mimic gettext and other translation functions. Please refer to this official Django documentation which is straight forward.


7.2. I tried implementing JavascriptCatalog but could not get it working. Hence I wrote a small implementation of my own which just do the work for me in a small application.

In your javascript file, write a function that accepts the primary language text, English in our case and then return the translated text in the prefered language.

This function picks the prefered language from a hidden input field which was created along with the list of all available languages in step 4.1

<input type="hidden" id="current_language_code" name="current_language_code" value="{{LANGUAGE_CODE}}">


Javascript Code:

var m = {  
'select category': 'カテゴリを選んでください',
'No files found for matching criteria': 'ファイルが見つかりません',

};

function getCurrentLanguage() {
return document.getElementById('current_language_code').value;
}

function getLangText(text) {
if (getCurrentLanguage() == 'ja') {
return m[text];
}
return text;
}


Now use this code to translate messages returned by Javascript functions as below.

document.getElementById('file_msg').innerHTML = getLangText('No files found for matching criteria');


This approach has limitations like it has support for two languages. To add support for more languages, we need to modify the code.


Please connect in case of any concern.



Here is a list of some awesome python books
Host your Django Application for free on PythonAnyWhere.
- If you want full control of your application and server, you should consider 
DigitalOcean.
- Create a
 DigitalOcean account with this link and get $100 credits.


feature photo by JuniperPhoton on Unsplash
django translation   0   54389

Related Articles:
How to reset Django superuser password
This article explains 3 methods to reset the user password in Django, What command should be used to reset the superuser password from the terminal in Django application, Changing the user password in Django...
Encryption-Decryption in Python Django
How to encrypt and decrypt the content in Django, Encrypting the critical information in Django App, Encrypting username, email and password in Django, Django security...
How to upload an Image file in Django
This article explains the simple steps of uploading and storing an image in Django application, After storing the image, how to use it in Django template or emails, Uploading a file in Django, Storing image in Django model, Uploading and storing the image in Django model, HTML for multipart file upload...
Getting query params from request in Django
In this article, we will see how to access the query parameters from a request in the Django view, Accessing GET attribute of request, get() vs getlist() method of request in Django, query parameters Django,...

SUBSCRIBE
Please subscribe to get the latest articles in your mailbox.





DigitalOcean Referral Badge

Get a .COM for just $5.98!


© 2021-2022 Python Circle   Contact   Sponsor   Archive   Sitemap   Partner Sites: PythonSnippets.Dev  99Dev.Tools