Internationalization (i18n)
This page describes how to add or update translations for the django-crud-views packages and the example applications.
Overview
Translations live in each package's locale/ directory, following Django's standard layout:
<package>/locale/<lang>/LC_MESSAGES/django.po # source strings + translations
<package>/locale/<lang>/LC_MESSAGES/django.mo # compiled binary (generated)
The packages with translatable strings are:
| Package | Locale path |
|---|---|
crud_views |
crud_views/locale/ |
crud_views_workflow |
crud_views_workflow/locale/ |
| Example app | examples/bootstrap5/locale/ |
Requirements
GNU gettext must be installed:
# Debian/Ubuntu
sudo apt-get install gettext
# macOS
brew install gettext
Updating translations after code changes
When translatable strings are added or changed in Python or template files, regenerate the .po files and fill in any new entries.
1. Extract new strings using the taskfile tasks:
task msg-make-crud_views # crud_views package
task msg-make-example # examples/bootstrap5
Or manually:
# For crud_views package (run from within the package directory)
cd crud_views
python -m django makemessages -l de --settings=settings_i18n
# For crud_views_workflow package
cd crud_views_workflow
python -m django makemessages -l de --settings=settings_i18n
# For the example app
cd examples/bootstrap5
python manage.py makemessages -l de
settings_i18n.pyis a minimal Django settings file at the repo root used only for management commands.
makemessages updates the .po file in-place. Existing translations are preserved; new strings appear with an empty msgstr ""; strings that no longer exist are marked with #~ (obsolete).
2. Edit the .po file and fill in the empty msgstr values for the new strings. Remove any #, fuzzy flags after reviewing the suggested translations.
3. Compile to binary using the taskfile tasks:
task msg-comp-crud_views # crud_views package
task msg-comp-example # examples/bootstrap5
Or manually:
# For crud_views and crud_views_workflow (run from repo root)
python -m django compilemessages --settings=settings_i18n
# For the example app
cd examples/bootstrap5
python manage.py compilemessages
4. Commit both .po and .mo files.
The
.mofiles are committed so that the package works out of the box without requiring a compile step after installation.
Adding a new language
1. Add the language to the example project settings (examples/bootstrap5/project/settings.py):
from django.utils.translation import gettext_lazy as _
LANGUAGES = [
("en", _("English")),
("de", _("German")),
("fr", _("French")), # new
]
2. Run makemessages for each package with the new locale code:
cd crud_views
python -m django makemessages -l fr --settings=settings_i18n
cd crud_views_workflow
python -m django makemessages -l fr --settings=settings_i18n
cd examples/bootstrap5
python manage.py makemessages -l fr
This creates locale/fr/LC_MESSAGES/django.po in each location.
3. Translate all strings in each new .po file.
4. Compile and commit as described above.
Using gettext_lazy for class-level strings
Strings defined at class level (model TextChoices, @transition decorator labels, form class attributes) must use gettext_lazy instead of gettext, because they are evaluated at import time before the request language is known:
# correct
from django.utils.translation import gettext_lazy as _
class Status(models.TextChoices):
NEW = "new", _("New")
ACTIVE = "active", _("Active")
# incorrect — evaluated once at import time, ignores active language
from django.utils.translation import gettext as _
Infrastructure checklist
For a Django project to serve translated content, all of the following must be in place:
django.middleware.locale.LocaleMiddlewareinMIDDLEWARE(afterSessionMiddleware, beforeCommonMiddleware)LANGUAGESlist insettings.pyLOCALE_PATHSpointing to the app'slocale/directory"django.template.context_processors.i18n"in the template context processorspath("i18n/", include("django.conf.urls.i18n"))inurls.py(for the language switcher)
See examples/bootstrap5/project/settings.py and examples/bootstrap5/project/urls.py for a working reference.