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-parler
Then, 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
TranslatableModel
as 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_getter
to preventNoneType
errors. - 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! 🌍