Django internationalization / Multiple Languages
Internationalization (i18n) in Django involves making your web application translatable into multiple languages.
Enable Internationalization in Settings
# Setting.py
# Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/
LANGUAGE_CODE = 'en'
LANGUAGES = [
('en', _('English')),
('id', _('Indonesian')),
]
PARLER_LANGUAGES = {
None: (
{'code': 'en'},
{'code': 'id'},
),
'default': {
'fallback': 'en',
'hide_untranslated': False,
}
}
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
LOCALE_PATHS = [
os.path.join(BASE_DIR, 'locale'),
]
Add Install App in Setting.py
1. Django Rosetta
django-rosetta
and django-parler
can be used to facilitate translation and internationalization in a Django project.
pip install django-rosetta
django-rosetta
is a Django application that eases the translation process by providing a web interface for editing .po
files.
App Configuration
Add rosetta
to your INSTALLED_APPS
in settings.py
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts.apps.AccountsConfig',
'rosetta', # for translation
]
Urls Configuration
add rosetta
in your urls.py
:
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.urls import include, path
from django.conf.urls.static import static
from django.conf import settings
urlpatterns = i18n_patterns(
path('admin/', admin.site.urls),
path('rosetta/', include('rosetta.urls')),
path('', include('accounts.urls')),
prefix_default_language = False
)
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Now, you can access the Rosetta interface at `http://127.0.0.1:8000/rosetta/files/project/` to manage translations through a user-friendly web interface.
2. Django Parler
django-parler
is an application for managing multilingual content in Django models. It provides an easy way to translate model fields.
Install django-parler
using pip:
pip install django-parler
Configuration App in setting.py
#Setting.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'accounts.apps.AccountsConfig',
'tinymce',
'parler', # for translation
]
#Setting.py
PARLER_LANGUAGES = {
None: (
{'code': 'en'},
{'code': 'id'},
),
'default': {
'fallback': 'en',
'hide_untranslated': False,
}
}
Using Parler in Models
To make a model translatable, inherit from TranslatableModel
and use TranslatedFields
for the fields you want to translate:
# MODEL.PY
# Requirements for translation
from django.utils.translation import gettext_lazy as _
from parler.models import TranslatableModel, TranslatedFields
class PostNews(TranslatableModel):
translations = TranslatedFields(
title=models.CharField(_("Title"), max_length=300),
content=models.TextField(_("Content"))
)
author = models.ForeignKey(User, on_delete=models.CASCADE)
images = models.ImageField(upload_to=rename_image, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
slug = models.SlugField(max_length=200, unique=True, blank=True)
def save(self, *args, **kwargs):
if not self.slug:
# Generate slug based on the translated title
self.slug = slugify(self.safe_translation_getter('title', any_language=True))
super().save(*args, **kwargs)
def __str__(self):
return self.safe_translation_getter('title', any_language=True)
python manage.py makemigrations
python manage.py migrate
# ADMINPY
from django.contrib import admin
from .models import User, PostNews, Category, Page
from tinymce.widgets import TinyMCE
from django.db import models
from tinymce.models import HTMLField
from parler.admin import TranslatableAdmin
admin.site.register(User)
# class PostNewsAdmin Content
admin.site.register(PostNews, TranslatableAdmin)
admin.site.register(Category, TranslatableAdmin)
class PageAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'created_at')
list_filter = ('author', 'created_at')
search_fields = ('title', 'author__username')
prepopulated_fields = {'slug': ('title',)}
formfield_overrides = {
models.TextField: {'widget': TinyMCE(attrs={'cols': 80, 'rows': 30})},
HTMLField: {'widget': TinyMCE(attrs={'cols': 80, 'rows': 30})},
}
admin.site.register(Page , PageAdmin)
Configuration in HTML Templates
{% extends 'home/base.html' %}
{% block title %}Fakultas EKonomi dan Bisnis UNM{% endblock %}
{% block content %}
{% load i18n %}
<div class="dropdown ms-3">
{% get_current_language as CURRENT_LANGUAGE %}
{% get_available_languages as AVAILABLE_LANGUAGES %}
{% get_language_info_list for AVAILABLE_LANGUAGES as languages %}
<a href="#" class="dropdown-toggle text-dark" data-bs-toggle="dropdown">
<small><i class="fas fa-globe-europe text-primary me-2"></i>
{% for language in languages %}
{% if language.code == CURRENT_LANGUAGE %}
{{ language.name_local }}
{% endif %}
{% endfor %}
</small>
</a>
<div class="dropdown-menu rounded">
{% for language in languages %}
<a class="dropdown-item {% if language.code == CURRENT_LANGUAGE %}active{% endif %}" href="{% if language.code == 'en' %}/{% else %}/{{ language.code }}/{% endif %}">
{{ language.name_local }}
</a>
{% endfor %}
</div>
</div>
django-admin makemessages -l en --ignore env
django-admin makemessages -l id --ignore env
Edit the .po
Files: After running makemessages
, a .po
file will be created or updated in the locale
directory of your app (e.g., locale/en/LC_MESSAGES/django.po
). Open this file to translate the extracted strings into the desired language. Each entry will look something like this:
msgid "Original text"
msgstr "Translated text"
django-admin compilemessages
References:
Video Channel youtube/com/@rootamin