Django Cartouche enables inline (in-HTML) .po translation editing for Django projects. Click on any string marked for translation in your browser to edit it directly during development.
Install as a development dependency:
pip install django-cartouche --group dev
# or with uv
uv add django-cartouche --devdjango-cartouche should only be installed in development environments. Configure it in your local/development settings file (e.g., settings/local.py or settings/dev.py):
# settings/local.py
from .base import *
DEBUG = True
INSTALLED_APPS += [
"cartouche",
]
MIDDLEWARE += [
"cartouche.middleware.CartoucheMiddleware", # Must be after LocaleMiddleware
]Conditionally include URLs in your urls.py:
from django.conf import settings
urlpatterns = [
# ...
]
if settings.DEBUG:
urlpatterns += [
path("cartouche/", include("cartouche.urls")),
]Set the lang attribute on your <html> element for locale detection:
{% load i18n %}
<!DOCTYPE html>
<html lang="{{ LANGUAGE_CODE }}">The editor only activates when DEBUG=True, but following these practices ensures cartouche is never present in production.
When a page renders, django-cartouche tracks all translation calls (gettext, pgettext) and injects a manifest of translated strings into the HTML response. The frontend script then walks the DOM, finds matching text, and wraps it in editable spans.
When you edit a string and save (blur or press Enter):
- The original source string (
msgid) is used to locate the entry in your.pofile - The
langattribute on<html>determines which locale's.pofile to update - The
.pofile is saved andcompilemessagesruns automatically
For example, if your source is English and you're viewing the site in Spanish (<html lang="es">):
{% trans "Welcome" %}displays "Bienvenido" (fromlocale/es/LC_MESSAGES/django.po)- Clicking on "Bienvenido" lets you edit the Spanish translation
- Saving updates
msgstrin the Spanish.pofile
To edit translations for a different language, switch your site's active locale first. Each language has its own .po file, and the lang attribute tells cartouche which one to modify.
The project ships with a simple demo project so you can see it in action locally:
cd demo && python manage.py runserver
Notice how changing the strings in-browser modifies your .po files and re-compiles them into .mo files.
uv sync # Install dependencies
uv run pre-commit install # Install git hooks (one-time)
ruff check src/ && ruff format src/ # Lint and format
pytest --cov # Run tests with coverageUse the interactive CLI for guided conventional commits:
uv run cz commitOr use standard git with conventional format:
git commit -m "feat: add new feature"
git commit -m "fix(compiler): handle edge case"If you end up using django-cartouche, I'd genuinely like to hear about your experience. Whether you've found it helpful, run into issues or have ideas for improvements, your feedback is welcome.