Terug naar blog

Django i18n: De complete gids voor het automatiseren van .po-bestandsvertaling

2026-01-28 9 min lezen
Django i18n: De complete gids voor het automatiseren van .po-bestandsvertaling

Als je ooit een Django-app in meer dan één taal hebt uitgebracht, ken je de procedure. Je wikkelt je strings in gettext(), draait makemessages, opent een .po-bestand met honderden regels en begint regel voor regel te vertalen. Voor twee talen en vijftig strings is dat te doen. Voor zes talen en vijfhonderd strings is het een volledige werkdag die je nooit meer terugkrijgt.

Deze gids behandelt de internationalisatie (i18n) pipeline van Django van begin tot eind, legt uit waar het misgaat en laat zien hoe je het pijnlijke deel automatiseert met AI-gestuurde vertaling.

De standaard Django i18n-workflow

Het ingebouwde i18n-systeem van Django is goed ontworpen. De kernlus ziet er zo uit:

Stap 1: Markeer strings voor vertaling in je Python-code en templates:

from django.utils.translation import gettext as _

def dashboard(request):
    welcome = _("Welcome back, %(name)s!") % {"name": request.user.first_name}
    return render(request, "dashboard.html", {"welcome": welcome})
{% load i18n %}
<h1>{% trans "Account Settings" %}</h1>
<p>{% blocktrans %}You have {{ count }} unread messages.{% endblocktrans %}</p>

Stap 2: Extraheer strings naar .po-bestanden:

python manage.py makemessages -l de -l fr -l nl

Dit scant je hele codebase en genereert één .po-bestand per taal, met daarin elke vertaalbare string:

#: myapp/views.py:4
msgid "Welcome back, %(name)s!"
msgstr ""

#: templates/dashboard.html:2
msgid "Account Settings"
msgstr ""

Stap 3: Vertaal elke lege msgstr met de hand.

Stap 4: Compileer de voltooide .po-bestanden naar binaire .mo-bestanden:

python manage.py compilemessages

Stappen 1, 2 en 4 zijn snel. Stap 3 is waar het proces vastloopt.

Waarom handmatig vertalen niet schaalt

Een typische Django-applicatie heeft ergens tussen de 200 en 2.000 vertaalbare strings. Vermenigvuldig dat met het aantal doeltalen en je kijkt naar een serieuze tijdsinvestering.

Dit is geen theoretische klacht. In een bekende Django Forum-thread meldde een ontwikkelaar dat hij meer dan 8 uur per .po-bestand besteedde aan handmatige vertalingen. Een Django core contributor beschreef meer dan 10 uur te besteden aan het verwerken van door de community ingediende vertalingen in een enkele release, voornamelijk aan review, opmaakcorrecties en het repareren van kapotte placeholders.

De problemen stapelen zich op in de loop van de tijd:

De grondoorzaak is dat vertaling wordt behandeld als een eenmalige gebeurtenis in plaats van een incrementeel, herhaalbaar proces.

Vertaling automatiseren met AI

Het idee is eenvoudig: in plaats van dat een mens elk .po-bestand opent en msgstr-waarden invult, leest een tool het bestand, stuurt onvertaalde strings naar een AI-model of vertaal-API, schrijft de resultaten terug en behoudt al het andere (opmerkingen, bestandsstructuur, placeholders, meervoudsvormen).

TranslateBot Django is een open-source pakket dat precies dit doet. Het sluit aan op het management command-systeem van Django, dus het past in de workflow die je al hebt.

Stapsgewijze installatie

1. Installeer het pakket

pip install translatebot-django

Of, als je uv gebruikt (aanbevolen):

uv add --dev translatebot-django

Installeren als dev-dependency is opzettelijk. Je hebt TranslateBot alleen nodig bij het genereren van vertalingen, niet tijdens runtime in productie.

2. Voeg toe aan INSTALLED_APPS

# settings.py
INSTALLED_APPS = [
    # ...
    "translatebot_django",
]

3. Configureer je AI-provider

# settings.py
import os

TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"

TranslateBot gebruikt LiteLLM onder de motorkap, wat betekent dat je elk van de 100+ modellen kunt inwisselen door één string te wijzigen:

Provider TRANSLATEBOT_MODEL-waarde
OpenAI gpt-4o-mini, gpt-4o
Anthropic claude-sonnet-4-5-20250929
Google gemini/gemini-2.5-flash
Azure OpenAI azure/gpt-4o-mini
DeepL Gebruik in plaats daarvan TRANSLATEBOT_PROVIDER = "deepl"

Voor DeepL installeer je de extra: pip install translatebot-django[deepl]. De gratis tier van DeepL geeft je 500.000 tekens per maand zonder kosten, wat voldoende is voor de meeste kleine tot middelgrote projecten.

4. Definieer je talen

# settings.py
LANGUAGES = [
    ("en", "English"),
    ("de", "German"),
    ("fr", "French"),
    ("nl", "Dutch"),
    ("ja", "Japanese"),
]

5. Voer de vertaling uit

python manage.py translate

Dat is het. TranslateBot scant je project op .po-bestanden, identificeert onvertaalde regels, stuurt ze in geoptimaliseerde batches naar het geconfigureerde AI-model en schrijft de resultaten terug. Bestaande vertalingen worden niet aangeraakt.

Om een enkele taal te vertalen:

python manage.py translate --target-lang nl

De uitvoer ziet er zo uit:

Translating to Dutch (nl)...
Found 42 strings to translate
Translating batch 1/2...
Translating batch 2/2...
Successfully translated 42 strings

6. Compileer zoals gebruikelijk

python manage.py compilemessages

Je volledige workflow is nu:

python manage.py makemessages -l de -l fr -l nl -l ja
python manage.py translate
python manage.py compilemessages

Drie commando's. Elke taal. Elke sprint.

Incrementeel van ontwerp

De belangrijkste functie voor een herhaalbare workflow is incrementele vertaling. TranslateBot vertaalt alleen regels waar msgstr leeg is. Als je 500 strings hebt en er 15 nieuw zijn deze sprint, worden alleen die 15 naar de API gestuurd.

Dit is om praktische redenen belangrijk:

  1. Kosten. Je betaalt alleen voor nieuwe strings, niet voor het hele bestand.
  2. Snelheid. Het vertalen van 15 strings duurt seconden, geen minuten.
  3. Stabiliteit. Vertalingen die je al hebt gereviewed en goedgekeurd worden nooit overschreven (tenzij je expliciet --overwrite meegeeft).

Placeholder-veiligheid

Django gebruikt verschillende placeholder-formaten: %(name)s, %s, %d, {0}, {name} en inline HTML-tags zoals <strong> of <a href="...">. Als een van deze beschadigd raakt bij vertaling, krijg je runtime-fouten of kapotte opmaak.

TranslateBot instrueert het AI-model om alle placeholder-formaten te behouden en valideert de uitvoer. Een string als:

Welcome to %(site_name)s! You have <strong>%(count)d</strong> new messages.

Wordt naar het Nederlands vertaald als:

Welkom bij %(site_name)s! Je hebt <strong>%(count)d</strong> nieuwe berichten.

Elke placeholder blijft intact.

Kwaliteit beheren met TRANSLATING.md

AI-modellen vertalen beter wanneer ze de context begrijpen. TranslateBot zoekt naar een TRANSLATING.md-bestand in je projectroot en neemt de inhoud op in elk vertaalverzoek.

# Translation Context

## About This Project
A B2B project management tool for construction companies.

## Terminology
- "project" means a construction project, not a software project
- "plan" means a building plan/blueprint, not a subscription plan
- Keep "Gantt chart" as-is in all languages

## Tone
- German: use formal "Sie" form (business context)
- French: use formal "vous" form
- Dutch: use informal "je" form

## Do Not Translate
- Brand name: "BuildFlow"
- Feature names: "SmartSchedule", "CostTracker"

Dit bestand wordt samen met je code versiebeheerd, zodat je hele team dezelfde vertaalcontext deelt. Je kunt ook per app TRANSLATING.md-bestanden plaatsen voor apps met gespecialiseerde terminologie. Een module voor medische dossiers en een facturatiemodule kunnen elk hun eigen woordenlijst hebben.

Voorvertoning voor commit

De --dry-run-vlag toont precies wat er vertaald zou worden zonder API-aanroepen te doen of bestanden te wijzigen:

python manage.py translate --target-lang fr --dry-run
Found 15 untranslated entries
Dry run mode: skipping LLM translation

Would translate 'Welcome to our site'
Would translate 'Hello, %(name)s!'
...

Dry run complete: 15 entries would be translated

Dit is nuttig voor een grote vertaalronde of bij het inwerken van een nieuw teamlid dat wil begrijpen wat het commando doet voordat ze zich committeren aan API-kosten.

CI/CD-integratie

Vertalingen die verouderen is onvermijdelijk zonder handhaving. TranslateBot bevat een check_translations management command ontworpen voor CI-pipelines:

# .github/workflows/ci.yml
jobs:
  translations:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: astral-sh/setup-uv@v4
        with:
          enable-cache: true
      - run: uv python install
      - run: uv sync --frozen
      - name: Install gettext
        run: sudo apt-get update && sudo apt-get install -y --no-install-recommends gettext
      - name: Check translations
        run: uv run python manage.py check_translations --makemessages

De --makemessages-vlag draait eerst makemessages -a --no-obsolete, zodat .po-bestanden de huidige broncode weerspiegelen voordat er gecontroleerd wordt. Als er onvertaalde of fuzzy regels zijn, eindigt het commando met code 1 en faalt de build:

locale/de/LC_MESSAGES/django.po: 2 untranslated, 0 fuzzy
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 1 fuzzy
CommandError: Translation check failed

De typische ontwikkelaarsworkflow wordt:

  1. Voeg nieuwe vertaalbare strings toe in een feature branch.
  2. CI faalt omdat die strings onvertaald zijn.
  3. Draai python manage.py translate lokaal.
  4. Commit de bijgewerkte .po-bestanden.
  5. CI slaagt.

Vertalingen raken nooit stilletjes uit sync.

Database-inhoud vertalen

Als je applicatie vertaalbare inhoud in de database opslaat (productnamen, blogtitels, categorielabels), integreert TranslateBot ook met django-modeltranslation:

pip install translatebot-django[modeltranslation]
# Translate all registered model fields
python manage.py translate --target-lang de --models

# Translate specific models only
python manage.py translate --target-lang de --models Product Category

Dezelfde incrementele logica is van toepassing: alleen velden waar de doeltaalwaarde leeg is worden vertaald.

Kostenvergelijking

Een van de meest gestelde vragen is of AI-vertaling kosteneffectief is vergeleken met alternatieven. Hier is een ruwe vergelijking voor een project met 500 vertaalbare strings in 5 talen:

Aanpak Geschatte kosten Tijdsinvestering
Handmatig (ontwikkelaarstijd) $0 uit eigen zak, 20-40+ uur Zeer hoog
Professionele vertaaldienst $500-2.000+ Laag (maar trage doorlooptijd)
SaaS-lokalisatieplatform $50-200/maand Gemiddeld
TranslateBot + GPT-4o-mini ~$0,05 (eenmalig) Minuten
TranslateBot + DeepL Free $0 (tot 500k tekens/maand) Minuten
TranslateBot + Claude/GPT-4o ~$0,30 (eenmalig) Minuten

De cijfers verschuiven afhankelijk van het aantal strings en doeltalen, maar het verschil in orde van grootte is consistent. Voor doorlopend onderhoud (het vertalen van de 20-50 nieuwe strings die elke sprint worden toegevoegd) zijn de AI-kosten in wezen nul.

Best practices

Begin met --dry-run. Voordat je de eerste echte vertaalronde draait, bekijk wat er gaat gebeuren. Dit bouwt vertrouwen op en vangt configuratieproblemen vroegtijdig op.

Commit .po-bestanden voor het vertalen. Als er iets misgaat, brengt git checkout je direct terug naar een schone staat.

Schrijf vanaf dag één een TRANSLATING.md. Zelfs een kort bestand met je projectbeschrijving en een paar terminologieregels verbetert de vertaalkwaliteit meetbaar.

Voeg check_translations toe aan CI. Deze ene stap voorkomt de meest voorkomende i18n-foutmodus: strings die gemarkeerd zijn voor vertaling maar nooit daadwerkelijk vertaald.

Gebruik gpt-4o-mini of DeepL voor kostenefficiëntie. Bewaar premiummodellen zoals GPT-4o of Claude voor projecten waar precisie ertoe doet, zoals marketingtekst, juridische tekst of domeinspecifieke terminologie.

Review kritieke strings. AI-vertalingen zijn goed genoeg voor de meeste UI-tekst, maar laat een native speaker alles reviewen dat juridisch bindend is, veiligheidskritisch is of klantgericht is in een context met hoge inzet.

Van uren naar seconden

Het i18n-framework van Django is uitstekend in het extraheren en compileren van vertalingen. De kloof zat altijd in de vertaalstap zelf, het vervelende, foutgevoelige werk van het invullen van honderden msgstr-waarden in meerdere talen.

TranslateBot dicht die kloof. Installeer het, wijs het naar een AI-provider en draai één commando. Nieuwe strings worden vertaald. Bestaande strings blijven onaangetast. Placeholders blijven intact. CI vangt alles op dat erdoorheen glipt.

Je .po-bestanden zijn niet langer een karwei maar gewoon weer een onderdeel van de build.

pip install translatebot-django

Ga aan de slag op translatebot.dev.

Stop met het handmatig bewerken van .po-bestanden

TranslateBot automatiseert Django-vertalingen met AI. Één commando, al uw talen, centen per vertaling.