Dacă ai lansat vreodată o aplicație Django în mai mult de o limbă, cunoști procedura. Înfășori string-urile în gettext(), rulezi makemessages, deschizi un fișier .po cu sute de intrări și începi să traduci linie cu linie. Pentru două limbi și cincizeci de string-uri, este tolerabil. Pentru șase limbi și cinci sute de string-uri, este o zi întreagă de muncă pe care nu o vei mai recupera niciodată.
Acest ghid acoperă pipeline-ul de internaționalizare (i18n) al Django de la început până la sfârșit, explică unde se defectează și arată cum să automatizezi partea dureroasă cu traducere bazată pe AI.
Fluxul de lucru standard Django i18n
Sistemul i18n încorporat al Django este bine proiectat. Bucla principală arată astfel:
Pasul 1: Marchează string-urile pentru traducere în codul Python și template-uri:
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>
Pasul 2: Extrage string-urile în fișiere .po:
python manage.py makemessages -l de -l fr -l nl
Aceasta scanează întreaga bază de cod și generează un fișier .po per limbă, conținând fiecare string traductibil:
#: myapp/views.py:4
msgid "Welcome back, %(name)s!"
msgstr ""
#: templates/dashboard.html:2
msgid "Account Settings"
msgstr ""
Pasul 3: Tradu fiecare msgstr gol manual.
Pasul 4: Compilează fișierele .po finalizate în fișiere binare .mo:
python manage.py compilemessages
Pașii 1, 2 și 4 sunt rapizi. Pasul 3 este locul unde procesul se destramă.
De ce traducerea manuală nu scalează
O aplicație Django tipică are între 200 și 2.000 de string-uri traductibile. Înmulțește asta cu numărul de limbi țintă și te uiți la un angajament serios de timp.
Aceasta nu este o plângere teoretică. Într-un thread Django Forum bine cunoscut, un dezvoltator a raportat că petrece peste 8 ore per fișier .po pentru traduceri manuale. Un contributor principal Django a descris că a petrecut peste 10 ore pentru a incorpora traducerile trimise de comunitate într-o singură lansare, în mare parte pentru revizuire, corecții de formatare și repararea placeholder-elor stricate.
Problemele se acumulează în timp:
- Placeholder-ele se strică. Copiază un string precum
Welcome, %(name)s!în Google Translate și vei primi adeseaWillkommen, %(Name)s!sauBienvenue, %(nom)s!. Acea corupție subtilă cauzează erori la rulare. - Consistența se pierde. Fără un glosar, "dashboard" este tradus ca "Instrumententafel" într-un fișier și "Dashboard" în altul. Trei luni mai târziu, nimeni nu-și amintește care a fost intenționat.
- Sprint-urile adaugă string-uri. Fiecare branch de funcționalitate adaugă noi string-uri traductibile. Chiar dacă ai plătit pentru o traducere completă trimestrul trecut, acum ai 40 de intrări netraduse răspândite în fișierele
.po. - Asistenții AI ajută o dată. Poți lipi un fișier
.poîn ChatGPT sau Claude și obține rezultate decente. Dar sprintul următor, când apar 15 string-uri noi, faci prompt de la zero, retraduci întregul fișier și speri că rămâne consistent cu ceea ce era deja acolo.
Cauza principală este că traducerea este tratată ca un eveniment unic în loc de un proces incremental și repetabil.
Automatizarea traducerii cu AI
Ideea este simplă: în loc ca o persoană să deschidă fiecare fișier .po și să completeze valorile msgstr, un instrument citește fișierul, trimite string-urile netraduse la un model AI sau API de traducere, scrie rezultatele înapoi și păstrează tot restul (comentarii, structura fișierului, placeholder-e, forme de plural).
TranslateBot Django este un pachet open-source care face exact acest lucru. Se conectează la sistemul de comenzi de management al Django, deci se potrivește în fluxul de lucru pe care îl ai deja.
Configurare pas cu pas
1. Instalează pachetul
pip install translatebot-django
Sau, dacă folosești uv (recomandat):
uv add --dev translatebot-django
Instalarea ca dependență de dezvoltare este intenționată. Ai nevoie de TranslateBot doar când generezi traduceri, nu la rulare în producție.
2. Adaugă la INSTALLED_APPS
# settings.py
INSTALLED_APPS = [
# ...
"translatebot_django",
]
3. Configurează furnizorul AI
# settings.py
import os
TRANSLATEBOT_API_KEY = os.getenv("OPENAI_API_KEY")
TRANSLATEBOT_MODEL = "gpt-4o-mini"
TranslateBot folosește LiteLLM sub capotă, ceea ce înseamnă că poți înlocui oricare din cele peste 100 de modele schimbând un singur string:
| Furnizor | Valoarea TRANSLATEBOT_MODEL |
|---|---|
| OpenAI | gpt-4o-mini, gpt-4o |
| Anthropic | claude-sonnet-4-5-20250929 |
gemini/gemini-2.5-flash |
|
| Azure OpenAI | azure/gpt-4o-mini |
| DeepL | Folosește TRANSLATEBOT_PROVIDER = "deepl" în schimb |
Pentru DeepL, instalează extra: pip install translatebot-django[deepl]. Nivelul gratuit al DeepL îți oferă 500.000 de caractere pe lună fără costuri, ceea ce este suficient pentru majoritatea proiectelor mici și medii.
4. Definește limbile
# settings.py
LANGUAGES = [
("en", "English"),
("de", "German"),
("fr", "French"),
("nl", "Dutch"),
("ja", "Japanese"),
]
5. Rulează traducerea
python manage.py translate
Asta e tot. TranslateBot scanează proiectul pentru fișiere .po, identifică intrările netraduse, le trimite la modelul AI configurat în loturi optimizate și scrie rezultatele. Traducerile existente rămân neatinse.
Pentru a traduce o singură limbă:
python manage.py translate --target-lang nl
Rezultatul arată astfel:
Translating to Dutch (nl)...
Found 42 strings to translate
Translating batch 1/2...
Translating batch 2/2...
Successfully translated 42 strings
6. Compilează ca de obicei
python manage.py compilemessages
Fluxul complet de lucru este acum:
python manage.py makemessages -l de -l fr -l nl -l ja
python manage.py translate
python manage.py compilemessages
Trei comenzi. Fiecare limbă. Fiecare sprint.
Incremental prin design
Cea mai importantă funcționalitate pentru un flux de lucru repetabil este traducerea incrementală. TranslateBot traduce doar intrările unde msgstr este gol. Dacă ai 500 de string-uri și 15 sunt noi în acest sprint, doar acele 15 sunt trimise la API.
Acest lucru contează din motive practice:
- Cost. Plătești doar pentru string-urile noi, nu pentru întregul fișier.
- Viteză. Traducerea a 15 string-uri durează secunde, nu minute.
- Stabilitate. Traducerile pe care le-ai revizuit și aprobat deja nu sunt niciodată suprascrise (cu excepția cazului în care trimiți explicit
--overwrite).
Siguranța placeholder-elor
Django folosește mai multe formate de placeholder: %(name)s, %s, %d, {0}, {name} și tag-uri HTML inline precum <strong> sau <a href="...">. Dacă oricare dintre acestea este alterat în traducere, primești erori la rulare sau markup stricat.
TranslateBot instruiește modelul AI să păstreze toate formatele de placeholder și validează rezultatul. Un string precum:
Welcome to %(site_name)s! You have <strong>%(count)d</strong> new messages.
Se traduce în olandeză ca:
Welkom bij %(site_name)s! Je hebt <strong>%(count)d</strong> nieuwe berichten.
Fiecare placeholder supraviețuiește intact.
Controlul calității cu TRANSLATING.md
Modelele AI traduc mai bine când înțeleg contextul. TranslateBot caută un fișier TRANSLATING.md în rădăcina proiectului și include conținutul acestuia în fiecare cerere de traducere.
# 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"
Acest fișier este versionat alături de cod, astfel încât întreaga echipă partajează același context de traducere. Poți de asemenea să plasezi fișiere TRANSLATING.md per aplicație pentru aplicațiile cu terminologie specializată. Un modul de dosare medicale și un modul de facturare pot avea fiecare propriul glosar.
Previzualizare înainte de commit
Flag-ul --dry-run arată exact ce ar fi tradus fără a face apeluri API sau a modifica fișiere:
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
Acest lucru este util înainte de o rundă mare de traducere sau când integrezi un nou membru al echipei care dorește să înțeleagă ce face comanda înainte de a se angaja la costurile API.
Integrare CI/CD
Traducerile care devin învechite sunt inevitabile fără aplicare. TranslateBot include o comandă de management check_translations proiectată pentru pipeline-uri CI:
# .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
Flag-ul --makemessages rulează mai întâi makemessages -a --no-obsolete, asigurând că fișierele .po reflectă codul sursă curent înainte de verificare. Dacă vreo intrare este netradusă sau fuzzy, comanda iese cu codul 1 și face build-ul să eșueze:
locale/de/LC_MESSAGES/django.po: 2 untranslated, 0 fuzzy
locale/nl/LC_MESSAGES/django.po: 0 untranslated, 1 fuzzy
CommandError: Translation check failed
Fluxul tipic de lucru al dezvoltatorului devine:
- Adaugă noi string-uri traductibile într-un branch de funcționalitate.
- CI eșuează pentru că acele string-uri sunt netraduse.
- Rulează
python manage.py translatelocal. - Comite fișierele
.poactualizate. - CI trece.
Traducerile nu se desincronizează niciodată în tăcere.
Traducerea conținutului din baza de date
Dacă aplicația ta stochează conținut traductibil în baza de date (nume de produse, titluri de postări pe blog, etichete de categorii), TranslateBot se integrează și cu 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
Aceeași logică incrementală se aplică: doar câmpurile unde valoarea limbii țintă este goală sunt traduse.
Comparație de costuri
Una dintre cele mai frecvente întrebări este dacă traducerea AI este rentabilă comparativ cu alternativele. Iată o comparație aproximativă pentru un proiect cu 500 de string-uri traductibile în 5 limbi:
| Abordare | Cost estimat | Investiție de timp |
|---|---|---|
| Manual (timpul dezvoltatorului) | $0 din buzunar, 20-40+ ore | Foarte mare |
| Serviciu profesional de traducere | $500-2.000+ | Scăzut (dar timp de răspuns lent) |
| Platformă SaaS de localizare | $50-200/lună | Mediu |
| TranslateBot + GPT-4o-mini | ~$0,05 (o singură dată) | Minute |
| TranslateBot + DeepL Free | $0 (până la 500k caractere/lună) | Minute |
| TranslateBot + Claude/GPT-4o | ~$0,30 (o singură dată) | Minute |
Cifrele variază în funcție de numărul de string-uri și limbile țintă, dar diferența de ordin de mărime este constantă. Pentru întreținerea continuă (traducerea celor 20-50 de string-uri noi adăugate în fiecare sprint), costul AI este practic zero.
Bune practici
Începe cu --dry-run. Înainte de prima traducere reală, previzualizează ce se va întâmpla. Aceasta construiește încredere și identifică problemele de configurare devreme.
Comite fișierele .po înainte de a traduce. Dacă ceva nu merge bine, git checkout te readuce instantaneu la o stare curată.
Scrie un TRANSLATING.md din prima zi. Chiar și un fișier scurt cu descrierea proiectului și câteva reguli de terminologie îmbunătățește măsurabil calitatea traducerii.
Adaugă check_translations la CI. Acest singur pas previne cel mai comun mod de eșec i18n: string-uri care au fost marcate pentru traducere dar niciodată traduse efectiv.
Folosește gpt-4o-mini sau DeepL pentru eficiența costurilor. Păstrează modelele premium precum GPT-4o sau Claude pentru proiectele unde precizia contează, precum textul de marketing, textul juridic sau terminologia specifică domeniului.
Revizuiește string-urile critice. Traducerile AI sunt suficient de bune pentru majoritatea textului UI, dar solicită unui vorbitor nativ să revizuiască orice este obligatoriu din punct de vedere juridic, critic pentru siguranță sau destinat clienților într-un context cu mize mari.
De la ore la secunde
Framework-ul i18n al Django excelează la extragerea și compilarea traducerilor. Lacuna a fost întotdeauna la pasul de traducere propriu-zis, munca plictisitoare și predispusă la erori de completare a sute de valori msgstr în mai multe limbi.
TranslateBot închide acea lacună. Instalează-l, indică-l spre un furnizor AI și rulează o comandă. String-urile noi sunt traduse. String-urile existente rămân neatinse. Placeholder-ele rămân intacte. CI prinde orice scapă.
Fișierele tale .po nu mai sunt o corvoadă și devin doar o altă parte a build-ului.
pip install translatebot-django
Începe la translatebot.dev.