Se hai lavorato con il framework di internazionalizzazione (i18n) integrato di Django, sai che gestisce bene le stringhe statiche. Avvolgere il testo in gettext() o usare il tag template {% trans %} estrae le stringhe in file .po, che i traduttori compilano. Il sistema è collaudato e funziona benissimo per codice e template.
Ma che dire del contenuto memorizzato nel tuo database?
Nomi di prodotti, titoli di articoli, descrizioni di categorie, risposte FAQ, contenuti generati dagli utenti. Niente di tutto questo si trova nel tuo codice sorgente. Il comando makemessages di Django non lo troverà mai, e i file .po non possono aiutarti qui. Se la tua applicazione serve contenuto dinamico agli utenti in più lingue, hai bisogno di una strategia diversa.
Ecco come fare: usa django-modeltranslation per aggiungere campi traducibili ai tuoi model, poi automatizza la traduzione con l'IA usando TranslateBot.
Pacchetti di Traduzione Database per Django
Diversi pacchetti di terze parti risolvono il problema della traduzione del database, ognuno con un'architettura diversa.
django-modeltranslation
Aggiunge colonne specifiche per lingua direttamente alle tabelle esistenti. Un campo title diventa title_en, title_de, title_fr e così via. Le query rimangono veloci perché tutto è nella stessa tabella. L'interfaccia di amministrazione mostra tutte le lingue affiancate.
- Pro: Nessun JOIN, query veloci, accesso trasparente tramite descrittori di campo, ecosistema maturo
- Contro: Modifiche allo schema per ogni nuova lingua, tabelle più larghe
django-parler
Crea una tabella di traduzione separata per ogni model. La tabella originale rimane pulita e le traduzioni sono memorizzate in una tabella correlata collegata tramite chiave esterna.
- Pro: Schema pulito, facile aggiungere lingue senza migrazioni
- Contro: Richiede JOIN per il contenuto tradotto, pattern di query leggermente più complessi
django-translations
Usa una singola tabella di traduzioni con una chiave esterna generica che punta a qualsiasi model. Tutte le traduzioni di tutti i model vanno in una tabella.
- Pro: Modifiche minime allo schema, funziona con qualsiasi model
- Contro: Le query con chiave esterna generica possono essere lente, API meno trasparente
Campo JSON Manuale
Puoi memorizzare le traduzioni in un JSONField:
class Product(models.Model):
name_translations = models.JSONField(default=dict)
# {"en": "Running Shoes", "de": "Laufschuhe", "fr": "Chaussures de course"}
- Pro: Nessuna dipendenza extra, flessibile
- Contro: Nessuna integrazione ORM, nessun supporto admin, tutto manuale
Quale Dovresti Usare?
Per la maggior parte dei progetti, django-modeltranslation è la scelta migliore. È il pacchetto più maturo, ha la migliore integrazione con l'admin di Django e mantiene tutti i dati nella stessa tabella per query veloci. Il compromesso (tabelle più larghe e una migrazione per ogni nuova lingua) è gestibile per la grande maggioranza delle applicazioni. Il resto di questa guida usa django-modeltranslation.
Configurazione di django-modeltranslation Passo dopo Passo
Passo 1: Installa il Pacchetto
TranslateBot include django-modeltranslation come dipendenza opzionale. Installa entrambi in una volta:
pip install translatebot-django[modeltranslation]
O se usi uv:
uv add --dev translatebot-django[modeltranslation]
Passo 2: Configura le Impostazioni di Django
Due cose contano in settings.py: l'ordine delle app e la lista delle lingue.
# 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'),
]
L'app modeltranslation deve venire prima di django.contrib.admin così può applicare le patch alle classi admin per mostrare i campi di traduzione.
Passo 3: Registra i Model per la Traduzione
Crea un file translation.py in ogni app che ha model traducibili. Per un'app di e-commerce:
# 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')
Includi solo campi che contengono testo leggibile dall'uomo. Non registrare campi come slug, price o sku.
Passo 4: Crea ed Esegui le Migrazioni
python manage.py makemigrations
python manage.py migrate
Dopo questo, la tua tabella shop_product ha nuove colonne:
| Colonna | Tipo |
|---|---|
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 |
Ogni lingua definita in LANGUAGES ottiene la propria colonna per ogni campo registrato.
Il Problema: Campi di Traduzione Vuoti
Ora hai lo schema pronto, ma ogni colonna _de, _fr e _nl è vuota. Se hai 500 prodotti con 3 campi traducibili e 3 lingue target, sono 4.500 campi vuoti in attesa di essere compilati.
Tradurre manualmente quel contenuto non è realistico. Anche con un servizio di traduzione professionale, dovresti esportare i dati, inviarli, aspettare la consegna e reimportare i risultati. Per un piccolo team o uno sviluppatore singolo, questo di solito significa che la funzionalità non viene mai rilasciata.
È qui che entra in gioco TranslateBot.
Automatizzare le Traduzioni con TranslateBot
Il comando di gestione translate di TranslateBot può popolare tutti quei campi vuoti usando l'IA. Configura prima la tua chiave API:
# settings.py
TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini" # Fast and cost-effective
Poi traduci tutti i model registrati in una lingua target:
python manage.py translate --target-lang de --models
Quel singolo comando trova ogni model registrato con django-modeltranslation, identifica i campi vuoti per la lingua target e li riempie con traduzioni generate dall'IA.
Traduci Model Specifici
Se vuoi tradurre solo i prodotti e non le categorie:
python manage.py translate --target-lang de --models Product
O più model specifici:
python manage.py translate --target-lang de --models Product Category
Anteprima con Dry Run
Visualizza sempre l'anteprima prima di scrivere nel database:
python manage.py translate --target-lang de --models --dry-run
Questo mostra esattamente cosa verrà tradotto senza modificare alcun record.
Ritradurre Contenuto Esistente
Per impostazione predefinita, TranslateBot salta i campi che hanno già una traduzione. Per sovrascrivere le traduzioni esistenti (ad esempio, dopo aver migliorato il modello IA o aggiunto contesto):
python manage.py translate --target-lang de --models --overwrite
Traduci Tutte le Lingue in Una Volta
Se ometti --target-lang e hai LANGUAGES definito nelle impostazioni, TranslateBot traduce in tutte le lingue configurate:
python manage.py translate --models
Come Funziona la Pipeline di Traduzione
Ecco cosa succede quando esegui il comando di traduzione.
-
Scoperta. TranslateBot interroga il registro di django-modeltranslation per trovare tutti i model registrati e i loro campi traducibili.
-
Rilevamento della fonte. Per ogni record, legge il contenuto sorgente. Controlla prima il campo base (es.,
name), poi ricade sul primo campo specifico per lingua che è popolato (es.,name_en). I record senza contenuto sorgente vengono saltati. -
Raggruppamento in batch. I record vengono raggruppati in batch e inviati al fornitore di IA. Questo mantiene le chiamate API efficienti e evita di raggiungere i limiti di frequenza.
-
Traduzione. Ogni batch viene tradotto usando il modello IA configurato. Puoi usare qualsiasi fornitore LLM supportato da LiteLLM (OpenAI, Anthropic, Google, Azure e molti altri) o DeepL.
-
Scritture atomiche. Tutti gli aggiornamenti del database per un'esecuzione di traduzione sono avvolti in una singola transazione. Se qualcosa va storto, come un errore API o una violazione di vincolo del database, nessun dato parziale viene salvato. Tutto o niente.
Esempio di Flusso di Lavoro Completo
Ecco un esempio completo dalla definizione del model al contenuto tradotto, usando un model Product di e-commerce.
Definisci il 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
Registra per la Traduzione
# shop/translation.py
from modeltranslation.translator import register, TranslationOptions
from .models import Product
@register(Product)
class ProductTranslationOptions(TranslationOptions):
fields = ('name', 'description', 'short_description')
Esegui le Migrazioni
python manage.py makemigrations shop
python manage.py migrate
Aggiungi Contesto di Traduzione (Opzionale)
Crea un file TRANSLATING.md nella root del progetto per dare all'IA contesto sul dominio del prodotto:
# 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
Traduci
# 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
Verifica nell'Admin
Apri l'admin di Django e vai a qualsiasi prodotto. Vedrai i campi di traduzione popolati:
- Name [de]: Ultraleichte Trail-Laufschuhe
- Description [de]: Diese leichten Trail-Laufschuhe bieten hervorragenden Grip...
- Short description [de]: Leicht, schnell und griffig auf jedem Untergrund.
Ripeti per ogni lingua target:
python manage.py translate --target-lang fr --models Product
python manage.py translate --target-lang nl --models Product
O traduci tutte le lingue in una volta:
python manage.py translate --models Product
Buone Pratiche
Esegui il backup del database prima di eseguire traduzioni massive in produzione. TranslateBot usa transazioni atomiche, quindi un'esecuzione fallita non lascerà dati parziali. Ma avere un backup ti dà un modo per tornare indietro se la qualità della traduzione non è quella attesa.
# PostgreSQL example
pg_dump mydb > backup_before_translation.sql
Usa prima il dry run. Esegui sempre con --dry-run prima di applicare traduzioni a un nuovo model o lingua. Rivedi l'output per assicurarti che il contenuto sorgente venga rilevato correttamente e le traduzioni sembrino ragionevoli.
Traduci un model alla volta per database grandi. Questo rende più facile rivedere i risultati e rieseguire model specifici se necessario.
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
Aggiungi contesto di traduzione. Un file TRANSLATING.md con terminologia specifica del dominio e linee guida sul tono migliora significativamente la qualità della traduzione. Questo è particolarmente importante per campi specializzati come medicina, diritto o prodotti tecnici.
Mantieni la lingua sorgente popolata. TranslateBot legge dal campo base o dal campo della lingua sorgente. Assicurati che il tuo flusso di inserimento dati compili sempre la lingua sorgente. Campi sorgente vuoti significano traduzioni vuote.
Combina con la traduzione di file PO per copertura completa. Traduci sia le stringhe del codice che il contenuto del database:
# 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
In questo modo ogni stringa che i tuoi utenti vedono, che provenga da un template o dal database, è tradotta.
Prossimi Passi
- Leggi il riferimento completo dei comandi per tutte le opzioni disponibili
- Configura l'integrazione CI per controllare automaticamente le traduzioni mancanti
- Esplora i modelli IA supportati per trovare il miglior equilibrio tra qualità e costo per il tuo progetto