If you're building a Django app that needs to support more than one language, Django's built-in internationalisation (i18n) is a decent start. But if you want to go further — like translating model fields, managing multilingual content, and switching language context dynamically — Django-parler is the tool you want.
This guide is aimed at beginners and covers everything from installation to usage, with best practices and practical examples.
🌍 Why Use Django-parler?
Django itself provides tools for translating strings in templates and Python code. Still, it doesn't offer a clean way to make database models translatable — to have fields that store multiple language versions.
Django-parler solves this with a well-designed API and seamless integration into Django admin and queries.
🔧 Installation and Basic Configuration
First, install the package:
pip install django-parlerThen, add it to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
...
'parler',
]Set your supported languages:
LANGUAGE_CODE = 'en'
LANGUAGES = [
('en', 'English'),
('pl', 'Polski'),
]
PARLER_LANGUAGES = {
None: (
{'code': 'en'},
{'code': 'pl'},
),
'default': {
'fallbacks': ['en'],
'hide_untranslated': False,
},
}🧱 Making a Model Translatable
Let's say you want to create a Category model in which each language's name and slug should differ.
Here's how to do it with parler:
from django.db import models
from parler.models import TranslatableModel, TranslatedFields
class Category(TranslatableModel):
translations = TranslatedFields(
name=models.CharField(max_length=200),
slug=models.SlugField(max_length=200, unique=True),
)
def __str__(self):
return self.safe_translation_getter('name', any_language=True)Key points:
- Use
TranslatableModelas your base class. - Define translatable fields inside
TranslatedFields(). - Use
safe_translation_getter()to safely get the translated value.
🛠 Using Translations in the Admin
Django-parler provides an admin mixin to show translation tabs automatically:
from django.contrib import admin
from parler.admin import TranslatableAdmin
from .models import Category
@admin.register(Category)
class CategoryAdmin(TranslatableAdmin):
list_display = ('__str__',)You'll now see tabs for each language when editing an object in the admin.
🔍 Querying Translatable Models
To avoid duplicate entries or incorrect results, always use .translated() when querying:
from .models import Category
# Only get categories that are translated into the current language
Category.objects.translated('pl').filter(translations__is_published=True)Or to get only those that exist in the current request's language:
from django.utils.translation import get_language
Category.objects.translated(get_language()).all()⚠️ Avoid using .filter(translations__...) without .translated(...) or .distinct() — this can lead to duplicate rows in querysets.
🎯 Rendering Translations in Templates
Use safe_translation_getter() to access values in templates:
{{ category.safe_translation_getter:"name" }}Or use the standard property (like category.name) if you're sure the model is correctly translated in the context.
🧪 Testing Translations
Use Django's override context to test translations:
from django.utils.translation import override
with override('pl'):
category = Category.objects.first()
print(category.name) # Should be in Polish🧹 Best Practices
- Use
safe_translation_getterto preventNoneTypeerrors. - Always use
.translated()when filtering by translatable fields. - Never mix translated and untranslated queries unless you use
.distinct(). - Use admin mixins to have a smooth experience when editing translations.
- Don't duplicate logic — define fallbacks and supported languages in one place (
settings.py).
✅ Summary
Django-parler is a powerful tool for multilingual content in Django. With minimal configuration, you can:
- Translate model fields.
- Filter and fetch content in the current language.
- Provide a seamless admin experience.
Stay tuned, and happy translating! 🌍