Als je met Django's ingebouwde internationalisatie (i18n) framework hebt gewerkt, weet je dat het statische strings goed afhandelt. Tekst wrappen in gettext() of de {% trans %} template tag gebruiken extraheert strings naar .po-bestanden, die vertalers invullen. Het systeem is beproefd en werkt uitstekend voor code en templates.
Maar hoe zit het met de content die in je database is opgeslagen?
Productnamen, artikeltitels, categoriebeschrijvingen, FAQ-antwoorden, door gebruikers gegenereerde content. Niets hiervan staat in je broncode. Django's makemessages-commando zal het nooit vinden, en .po-bestanden kunnen je hier niet helpen. Als je applicatie dynamische content aan gebruikers in meerdere talen serveert, heb je een andere strategie nodig.
Zo doe je het: gebruik django-modeltranslation om vertaalbare velden aan je modellen toe te voegen, en automatiseer vervolgens de vertaling met AI met behulp van TranslateBot.
Django Database-vertaalpakketten
Verschillende third-party pakketten lossen het probleem van databasevertaling op, elk met een andere architectuur.
django-modeltranslation
Voegt taalspecifieke kolommen direct toe aan je bestaande tabellen. Een title-veld wordt title_en, title_de, title_fr, enzovoort. Queries blijven snel omdat alles in dezelfde tabel staat. De admin-interface toont alle talen naast elkaar.
- Voordelen: Geen JOINs, snelle queries, transparante toegang via velddescriptors, volwassen ecosysteem
- Nadelen: Schemawijzigingen voor elke nieuwe taal, bredere tabellen
django-parler
Maakt een aparte vertaaltabel voor elk model. De originele tabel blijft schoon, en vertalingen worden opgeslagen in een gerelateerde tabel via een foreign key.
- Voordelen: Schoon schema, makkelijk talen toevoegen zonder migraties
- Nadelen: Vereist JOINs voor vertaalde content, iets complexere querypatronen
django-translations
Gebruikt een enkele vertaaltabel met een generieke foreign key die terugwijst naar elk model. Alle vertalingen voor alle modellen gaan in een tabel.
- Voordelen: Minimale schemawijzigingen, werkt met elk model
- Nadelen: Generieke foreign key queries kunnen traag zijn, minder transparante API
Handmatig JSON-veld
Je kunt vertalingen opslaan in een JSONField:
class Product(models.Model):
name_translations = models.JSONField(default=dict)
# {"en": "Running Shoes", "de": "Laufschuhe", "fr": "Chaussures de course"}
- Voordelen: Geen extra afhankelijkheden, flexibel
- Nadelen: Geen ORM-integratie, geen admin-ondersteuning, alles handmatig
Welke moet je gebruiken?
Voor de meeste projecten is django-modeltranslation de beste keuze. Het is het meest volwassen pakket, heeft de beste Django admin-integratie, en houdt alle data in dezelfde tabel voor snelle queries. De afweging (bredere tabellen en een migratie per nieuwe taal) is beheersbaar voor de overgrote meerderheid van applicaties. De rest van deze handleiding gebruikt django-modeltranslation.
django-modeltranslation stap voor stap instellen
Stap 1: Installeer het pakket
TranslateBot bundelt django-modeltranslation als optionele afhankelijkheid. Installeer beide tegelijk:
pip install translatebot-django[modeltranslation]
Of als je uv gebruikt:
uv add --dev translatebot-django[modeltranslation]
Stap 2: Configureer Django-instellingen
Twee dingen zijn belangrijk in settings.py: de app-volgorde en de talenlijst.
# settings.py
INSTALLED_APPS = [
'modeltranslation', # Must be BEFORE django.contrib.admin
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Your apps
'shop',
'translatebot_django',
]
LANGUAGE_CODE = 'en'
LANGUAGES = [
('en', 'English'),
('de', 'German'),
('fr', 'French'),
('nl', 'Dutch'),
]
De modeltranslation-app moet voor django.contrib.admin staan zodat het de admin-klassen kan patchen om vertaalvelden te tonen.
Stap 3: Registreer modellen voor vertaling
Maak een translation.py-bestand in elke app die vertaalbare modellen heeft. Voor een e-commerce winkel-app:
# shop/translation.py
from modeltranslation.translator import register, TranslationOptions
from .models import Product, Category
@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('name', 'description', 'short_description')
@register(Category)
class CategoryTranslationOptions(TranslationOptions):
fields = ('name', 'description')
Neem alleen velden op die door mensen leesbare tekst bevatten. Registreer geen velden zoals slug, price of sku.
Stap 4: Maak en voer migraties uit
python manage.py makemigrations
python manage.py migrate
Hierna heeft je shop_product-tabel nieuwe kolommen:
| Column | Type |
|---|---|
name |
varchar(200) |
name_en |
varchar(200) |
name_de |
varchar(200) |
name_fr |
varchar(200) |
name_nl |
varchar(200) |
description |
text |
description_en |
text |
description_de |
text |
description_fr |
text |
description_nl |
text |
short_description |
text |
short_description_en |
text |
short_description_de |
text |
short_description_fr |
text |
short_description_nl |
text |
Elke taal die je in LANGUAGES hebt gedefinieerd krijgt een eigen kolom voor elk geregistreerd veld.
Het probleem: Lege vertaalvelden
Je hebt nu het schema, maar elke _de, _fr en _nl kolom is leeg. Als je 500 producten hebt met 3 vertaalbare velden en 3 doeltalen, zijn dat 4.500 lege velden die wachten om ingevuld te worden.
Die content handmatig vertalen is niet realistisch. Zelfs met een professionele vertaaldienst moet je de data exporteren, versturen, wachten op oplevering en de resultaten weer importeren. Voor een klein team of solodev betekent dit meestal dat de feature nooit uitkomt.
Hier komt TranslateBot in beeld.
Vertalingen automatiseren met TranslateBot
TranslateBot's translate management-commando kan al die lege velden vullen met AI. Configureer eerst je API-sleutel:
# settings.py
TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini" # Fast and cost-effective
Vertaal vervolgens alle geregistreerde modellen naar een doeltaal:
python manage.py translate --target-lang de --models
Dat ene commando vindt elk model dat geregistreerd is bij django-modeltranslation, identificeert velden die leeg zijn voor de doeltaal, en vult ze met door AI gegenereerde vertalingen.
Specifieke modellen vertalen
Als je alleen producten wilt vertalen en geen categorieen:
python manage.py translate --target-lang de --models Product
Of meerdere specifieke modellen:
python manage.py translate --target-lang de --models Product Category
Voorbeeld bekijken met dry run
Bekijk altijd een voorbeeld voordat je naar de database schrijft:
python manage.py translate --target-lang de --models --dry-run
Dit toont je precies wat er vertaald wordt zonder records te wijzigen.
Bestaande content opnieuw vertalen
Standaard slaat TranslateBot velden over die al een vertaling hebben. Om bestaande vertalingen te overschrijven (bijvoorbeeld na het verbeteren van je AI-model of het toevoegen van context):
python manage.py translate --target-lang de --models --overwrite
Alle talen tegelijk vertalen
Als je --target-lang weglaat en LANGUAGES hebt gedefinieerd in je instellingen, vertaalt TranslateBot naar alle geconfigureerde talen:
python manage.py translate --models
Hoe de vertaalpipeline werkt
Dit is wat er gebeurt wanneer je het translate-commando uitvoert.
-
Ontdekking. TranslateBot bevraagt het register van django-modeltranslation om alle geregistreerde modellen en hun vertaalbare velden te vinden.
-
Brondetectie. Voor elk record leest het de broncontent. Het controleert eerst het basisveld (bijv.
name), en valt dan terug op het eerste ingevulde taalspecifieke veld (bijv.name_en). Records zonder broncontent worden overgeslagen. -
Batching. Records worden gegroepeerd in batches en naar de AI-provider gestuurd. Dit houdt API-aanroepen efficient en voorkomt het bereiken van rate limits.
-
Vertaling. Elke batch wordt vertaald met het geconfigureerde AI-model. Je kunt elke LLM-provider gebruiken die door LiteLLM wordt ondersteund (OpenAI, Anthropic, Google, Azure en vele anderen) of DeepL.
-
Atomaire writes. Alle database-updates voor een vertaalrun worden in een enkele transactie gewikkeld. Als er iets misgaat, zoals een API-fout of een databaseconstraint-schending, worden er geen gedeeltelijke data opgeslagen. Alles of niets.
Compleet workflowvoorbeeld
Hier is een volledig voorbeeld van modeldefinitie tot vertaalde content, met een e-commerce Product-model.
Definieer het model
# shop/models.py
from django.db import models
class Product(models.Model):
name = models.CharField(max_length=200)
description = models.TextField()
short_description = models.CharField(max_length=500, blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
sku = models.CharField(max_length=50, unique=True)
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.name
Registreer voor vertaling
# shop/translation.py
from modeltranslation.translator import register, TranslationOptions
from .models import Product
@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('name', 'description', 'short_description')
Voer migraties uit
python manage.py makemigrations shop
python manage.py migrate
Voeg vertaalcontext toe (optioneel)
Maak een TRANSLATING.md-bestand in de root van je project om de AI context te geven over je productdomein:
# Translation Context
## About This Project
E-commerce store for outdoor sports equipment.
## Terminology
- "trail runners" refers to trail running shoes, not people
- Keep brand names (Nike, Salomon, Arc'teryx) untranslated
- "Gore-Tex" is a brand name, do not translate
## Tone
- Use informal "du" form in German
- Product descriptions should sound enthusiastic but not exaggerated
Vertaal
# Preview first
python manage.py translate --target-lang de --models Product --dry-run
# Apply translations
python manage.py translate --target-lang de --models Product
Output:
Translating Product model fields to German (de)...
Found 142 products with untranslated fields
Translating batch 1/15...
Translating batch 2/15...
...
Translating batch 15/15...
Successfully translated 142 products
Verifieer in de admin
Open de Django admin en ga naar een willekeurig product. Je ziet de vertaalvelden ingevuld:
- Name [de]: Ultraleichte Trail-Laufschuhe
- Description [de]: Diese leichten Trail-Laufschuhe bieten hervorragenden Grip...
- Short description [de]: Leicht, schnell und griffig auf jedem Untergrund.
Herhaal voor elke doeltaal:
python manage.py translate --target-lang fr --models Product
python manage.py translate --target-lang nl --models Product
Of vertaal alle talen tegelijk:
python manage.py translate --models Product
Best practices
Maak een back-up van je database voordat je bulkvertalingen op productie uitvoert. TranslateBot gebruikt atomaire transacties, dus een mislukte run laat geen gedeeltelijke data achter. Maar een back-up geeft je een manier om terug te draaien als de vertaalkwaliteit niet is wat je verwachtte.
# PostgreSQL example
pg_dump mydb > backup_before_translation.sql
Gebruik eerst dry run. Voer altijd uit met --dry-run voordat je vertalingen toepast op een nieuw model of taal. Bekijk de output om te controleren of de broncontent correct wordt gedetecteerd en de vertalingen er redelijk uitzien.
Vertaal een model tegelijk voor grote databases. Dit maakt het makkelijker om resultaten te beoordelen en specifieke modellen opnieuw uit te voeren indien nodig.
python manage.py translate --target-lang de --models Product
python manage.py translate --target-lang de --models Category
python manage.py translate --target-lang de --models Article
Voeg vertaalcontext toe. Een TRANSLATING.md-bestand met domeinspecifieke terminologie en toonrichtlijnen verbetert de vertaalkwaliteit aanzienlijk. Dit is vooral belangrijk voor gespecialiseerde gebieden zoals geneeskunde, recht of technische producten.
Houd je brontaal ingevuld. TranslateBot leest uit het basisveld of het brontaalveld. Zorg ervoor dat je data-invoerworkflow altijd de brontaal invult. Lege bronvelden betekenen lege vertalingen.
Combineer met PO-bestandsvertaling voor volledige dekking. Vertaal zowel je codestrings als databasecontent:
# Static strings in code and templates
python manage.py makemessages -l de -l fr -l nl
python manage.py translate
python manage.py compilemessages
# Dynamic content in the database
python manage.py translate --models
Op deze manier is elke string die je gebruikers zien, of deze nu uit een template of de database komt, vertaald.
Volgende stappen
- Lees de volledige commandoreferentie voor alle beschikbare opties
- Stel CI-integratie in om automatisch te controleren op ontbrekende vertalingen
- Verken ondersteunde AI-modellen om de beste balans tussen kwaliteit en kosten voor je project te vinden