Django Modeltranslation
django-modeltranslation is a Django application that allows you to translate fields of your models into multiple languages. It uses a registration approach, dynamically adding translation fields to your models based on settings. The current version is 0.20.2, and it maintains a regular release cadence with patch and minor updates.
Warnings
- breaking Version 0.20.0 introduced significant changes, requiring Python 3.10+ and Django 3.2+. Older versions of Python and Django are no longer supported. Ensure your environment meets these requirements before upgrading.
- breaking The behavior of the `FALLBACK_LANGUAGES` setting changed significantly in version 0.20.0. If `FALLBACK_LANGUAGES` is empty or not set, it now defaults to the `LANGUAGE_CODE` if the explicitly requested language isn't found. This can alter how empty translation fields are resolved, potentially displaying the default language when previously nothing might have been shown. Review your `FALLBACK_LANGUAGES` configuration and application logic.
- gotcha After defining `TranslationOptions` for a model or modifying its translated fields, you MUST run `python manage.py makemigrations`, `python manage.py migrate`, AND then `python manage.py sync_translation_fields`. Failing to run `sync_translation_fields` will result in the actual database columns for translations (e.g., `name_en`, `name_fr`) not being created or updated, leading to `DoesNotExist` or `AttributeError` when accessing them.
- gotcha For translated fields to appear and be editable in the Django admin interface, you must use `modeltranslation.admin.TranslationAdmin` (or a subclass) for your registered models, not `django.contrib.admin.ModelAdmin`. Without `TranslationAdmin`, the additional language fields will not be displayed.
- gotcha While you can directly access translation fields like `instance.my_field_en`, it's generally better practice to use `instance.my_field` when the current request's language is set correctly (via `django.utils.translation.activate` or `with translation.override`). This allows your code to adapt to the active language automatically. Direct access to `_en` suffixes bypasses language negotiation.
Install
-
pip install django-modeltranslation
Imports
- register
from modeltranslation.decorators import register
- TranslationOptions
from modeltranslation.translator import TranslationOptions
- translator
from modeltranslation.translator import translator
- TranslationAdmin
from modeltranslation.admin import TranslationAdmin
Quickstart
# --- settings.py ---
# Add 'modeltranslation' and your app to INSTALLED_APPS
INSTALLED_APPS = [
# ... other apps
'modeltranslation',
'yourapp', # Your Django app containing translated models
]
# Define the languages available for translation
LANGUAGES = (
('en', 'English'),
('fr', 'French'),
# Add other languages as needed
)
# Optional: Configure fallback languages behavior
# FALLBACK_LANGUAGES = {'default': ('en', 'fr'), 'fr': ('en',)}
# --- yourapp/models.py ---
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=255)
description = models.TextField(blank=True, null=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return self.name
# --- yourapp/translation.py ---
from modeltranslation.decorators import register
from modeltranslation.translator import TranslationOptions
from .models import Product
@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('name', 'description',)
# --- yourapp/admin.py ---
from django.contrib import admin
from modeltranslation.admin import TranslationAdmin
from .models import Product
@admin.register(Product)
class ProductAdmin(TranslationAdmin):
list_display = ('name', 'price',) # 'name' will automatically display the current language
group_fieldsets = True # Optional: Groups translation fields under tabs in the admin
# Other Django Admin options can be added here
# --- Post-setup steps ---
# After adding the above code:
# 1. Run database migrations to create translation fields:
# python manage.py makemigrations yourapp
# python manage.py migrate
# 2. Synchronize translation fields (crucial for initial setup and field changes):
# python manage.py sync_translation_fields
# --- Accessing translated data ---
# from django.utils import translation
# product_instance = Product.objects.first()
# with translation.override('en'):
# print(product_instance.name) # Accesses 'name_en'
# with translation.override('fr'):
# print(product_instance.name) # Accesses 'name_fr'
# print(product_instance.name_en) # Direct access to English field
# print(product_instance.get_name_fr()) # Helper for specific language