Table des matières
Django i18n avec Traduction IA : Guide Complet de Configuration
Django est livré avec un framework d'internationalisation (i18n) mature construit sur GNU gettext. Lorsque vous combinez cette base avec la traduction assistée par IA, vous obtenez un flux de travail qui s'adapte d'un projet solo à une application de production multi-locale sans vous noyer dans le travail de traduction manuel.
Ce guide vous accompagne tout au long du processus : configurer Django pour l'i18n, marquer les chaînes, gérer les fichiers .po, automatiser la traduction avec l'IA et tout connecter à un pipeline CI/CD.
Points Clés
- Le système i18n de Django utilise GNU gettext — les chaînes sont marquées en Python et dans les templates, extraites dans des fichiers
.poet compilées en fichiers binaires.mopour une utilisation à l'exécution. - La traduction IA peut automatiser la traduction des fichiers
.po— les API de traduction automatique traitent les entrées non traduites en masse, réduisant des jours de travail manuel à quelques minutes. - Une étape de vérification qualité est essentielle — les traductions générées par IA doivent être vérifiées par des locuteurs natifs avant le déploiement en production, notamment pour le contenu orienté utilisateur.
- L'intégration CI/CD ferme la boucle — les pipelines automatisés peuvent extraire de nouvelles chaînes, les traduire, compiler les fichiers de messages et déployer sans intervention manuelle.
- Better i18n fournit un flux de travail géré — au lieu de créer des scripts personnalisés, vous pouvez synchroniser les fichiers
.po, gérer les traductions et automatiser tout le cycle de vie depuis une seule plateforme.
Qu'est-ce que Django i18n ?
Django i18n est le framework d'internationalisation intégré de Django qui vous permet de traduire votre application web en plusieurs langues. Il enveloppe GNU gettext pour fournir l'extraction de chaînes, la gestion des fichiers de traduction et le changement de langue à l'exécution — tout cela intégré aux templates, formulaires et au routage URL de Django.
Django sépare l'internationalisation (i18n) de la localisation (l10n). L'internationalisation est le processus de préparation de votre code à supporter plusieurs langues. La localisation est le processus de traduction effective du contenu et d'adaptation des formats pour un locale spécifique. Django gère les deux via son module django.utils.translation et la chaîne d'outils gettext.
Le framework prend en charge la traduction de :
- Les chaînes Python dans les vues, modèles et formulaires
- Le contenu des templates en utilisant des balises de template intégrées
- Les patterns URL pour le routage avec préfixe de locale
- Le formatage des dates, heures, nombres et devises via
django.utils.formats
Pour la référence officielle, consultez la documentation d'internationalisation de Django.
Configurer Django pour l'Internationalisation
Avant de marquer des chaînes pour la traduction, vous devez configurer les paramètres de Django et installer le middleware requis.
Configurer les Paramètres
Ouvrez votre settings.py et définissez ce qui suit :
# settings.py
from django.utils.translation import gettext_lazy as _
# Langue par défaut de l'application
LANGUAGE_CODE = "en"
# Activer le framework d'internationalisation
USE_I18N = True
# Activer le formatage localisé des dates, nombres, etc.
USE_L10N = True
# Activer les datetimes avec gestion des fuseaux horaires
USE_TZ = True
# Langues supportées par votre application
LANGUAGES = [
("en", _("English")),
("es", _("Spanish")),
("fr", _("French")),
("de", _("German")),
("ja", _("Japanese")),
]
# Où Django cherche les fichiers de traduction
LOCALE_PATHS = [
BASE_DIR / "locale",
]
Vous avez également besoin de LocaleMiddleware dans votre pile de middleware. Il doit venir après SessionMiddleware et avant CommonMiddleware :
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware", # Doit être ici
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
Créez la structure de répertoire locale :
mkdir -p locale/{es,fr,de,ja}/LC_MESSAGES
Marquer les Chaînes pour la Traduction
Django fournit deux fonctions principales pour marquer les chaînes traduisibles :
gettext()(aliasé en_()) — traduit la chaîne immédiatement à l'exécutiongettext_lazy()(aliasé en_()) — reporte la traduction jusqu'à ce que la chaîne soit rendue, ce qui est nécessaire pour le code au niveau du module comme les champs de modèle et les étiquettes de formulaire
Dans les vues (utiliser gettext) :
from django.utils.translation import gettext as _
def dashboard_view(request):
welcome_message = _("Welcome to your dashboard")
context = {
"title": _("Dashboard"),
"welcome": welcome_message,
}
return render(request, "dashboard.html", context)
Dans les modèles (utiliser gettext_lazy) :
from django.db import models
from django.utils.translation import gettext_lazy as _
class Article(models.Model):
title = models.CharField(
max_length=200,
verbose_name=_("Title"),
)
body = models.TextField(
verbose_name=_("Body"),
help_text=_("The main content of the article."),
)
created_at = models.DateTimeField(
auto_now_add=True,
verbose_name=_("Created at"),
)
class Meta:
verbose_name = _("Article")
verbose_name_plural = _("Articles")
def __str__(self):
return self.title
La distinction est importante : gettext_lazy renvoie un proxy de chaîne paresseux qui se résout dans la bonne langue lorsque la chaîne est réellement affichée. Les définitions de modèle sont évaluées une fois à l'importation ; utiliser gettext là-dedans figer la langue active lors de l'importation.
Balises de Traduction dans les Templates
Les templates Django utilisent {% load i18n %} pour accéder aux balises de traduction :
Traduction simple de chaîne avec {% trans %} :
{% load i18n %}
<h1>{% trans "Welcome to our site" %}</h1>
<p>{% trans "This content will be translated." %}</p>
Traduction de bloc avec {% blocktrans %} pour les chaînes contenant des variables :
{% load i18n %}
{% blocktrans with username=user.username %}
Hello, {{ username }}! You have new notifications.
{% endblocktrans %}
Pluralisation :
{% load i18n %}
{% blocktrans count counter=item_count %}
You have {{ counter }} item in your cart.
{% plural %}
You have {{ counter }} items in your cart.
{% endblocktrans %}
Définir le contexte de langue :
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<html lang="{{ LANGUAGE_CODE }}">
Internationalisation des URL
La fonction i18n_patterns de Django préfixe vos patterns URL avec le code de langue actif :
# urls.py
from django.conf.urls.i18n import i18n_patterns
from django.urls import path, include
urlpatterns = [
# URLs non localisées (admin, API, etc.)
path("api/", include("api.urls")),
]
urlpatterns += i18n_patterns(
path("", include("pages.urls")),
path("blog/", include("blog.urls")),
path("accounts/", include("accounts.urls")),
prefix_default_language=True,
)
Avec cette configuration, vos URL deviennent :
/en/blog/— Blog en anglais/es/blog/— Blog en espagnol/fr/blog/— Blog en français
Vous devriez également inclure la vue de changement de langue intégrée de Django :
from django.conf.urls.i18n import i18n_patterns
from django.urls import path, include
urlpatterns = [
path("i18n/", include("django.conf.urls.i18n")),
]
urlpatterns += i18n_patterns(
# ... vos patterns
)
Cela active la balise de template {% url 'set_language' %} qui permet aux utilisateurs de changer de langue via un formulaire POST.
Travailler avec les Fichiers .po et .mo
Le système de traduction de Django repose sur le format de fichier de GNU gettext. Comprendre ce pipeline est essentiel avant de l'automatiser.
Comment fonctionne gettext dans Django
Le flux de travail suit trois étapes :
- Extraire —
makemessagesanalyse vos fichiers Python et templates à la recherche de chaînes traduisibles et les écrit dans des fichiers.po(Portable Object). - Traduire — Les traducteurs (ou l'IA) remplissent le champ
msgstrpour chaquemsgiddans les fichiers.po. - Compiler —
compilemessagesconvertit les fichiers.poen fichiers binaires.mo(Machine Object) que Django lit à l'exécution pour des recherches rapides.
Extraire les Messages
Exécutez la commande d'extraction depuis la racine de votre projet :
# Extraire les messages pour toutes les langues configurées python manage.py makemessages --all --no-obsolete # Extraire pour une langue spécifique python manage.py makemessages -l es # Inclure les chaînes JavaScript (pour le catalogue JS i18n de Django) python manage.py makemessages -d djangojs --all
Le flag --no-obsolete supprime les entrées pour les chaînes qui n'existent plus dans votre code, gardant vos fichiers .po propres.
La Structure du Fichier .po
Après l'extraction, chaque locale obtient un fichier .po :
locale/
├── es/
│ └── LC_MESSAGES/
│ └── django.po
├── fr/
│ └── LC_MESSAGES/
│ └── django.po
└── de/
└── LC_MESSAGES/
└── django.po
Une entrée de fichier .po ressemble à ceci :
#: templates/dashboard.html:5 msgid "Welcome to your dashboard" msgstr "" #: myapp/models.py:12 msgid "Article" msgstr "" #. Translators: This is a button label #: templates/base.html:42 msgid "Submit" msgstr ""
Chaque entrée possède :
- Les commentaires
#:— références de fichier source et de ligne msgid— la chaîne originale (dans votre langue source)msgstr— la chaîne traduite (vide jusqu'à la traduction)- Les commentaires
#.— notes pour les traducteurs (ajoutées via les commentairesTranslators:dans votre code)
Compiler les Messages
Une fois les traductions terminées, compilez-les :
python manage.py compilemessages
Cela crée des fichiers .mo à côté des fichiers .po. Django charge ces fichiers binaires au démarrage pour des recherches de traduction rapides. Vous devez redémarrer votre serveur Django (ou les processus worker) après avoir compilé de nouvelles traductions.
Ajouter la Traduction IA à Django
La traduction manuelle des fichiers .po est précise mais lente. La traduction assistée par IA peut traiter des centaines d'entrées en quelques secondes, vous donnant un premier brouillon fonctionnel que les réviseurs humains peuvent ensuite affiner.
Analyser et Traduire les Fichiers .po avec Python
La bibliothèque polib fournit une API propre pour lire et écrire des fichiers .po par programme :
pip install polib openai
Voici un script qui traduit les entrées non traduites dans un fichier .po en utilisant une API de traduction IA :
# scripts/translate_po.py
import sys
import polib
from openai import OpenAI
client = OpenAI() # Utilise la variable d'environnement OPENAI_API_KEY
TARGET_LANGUAGES = {
"es": "Spanish",
"fr": "French",
"de": "German",
"ja": "Japanese",
}
def translate_text(text: str, target_language: str) -> str:
"""Traduit une seule chaîne en utilisant un modèle IA."""
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": (
f"You are a professional translator. Translate the following "
f"text to {target_language}. Preserve any Python format strings "
f"like %(name)s or {{variable}} exactly as they are. "
f"Return only the translated text, nothing else."
),
},
{"role": "user", "content": text},
],
temperature=0.3,
)
return response.choices[0].message.content.strip()
def translate_po_file(po_path: str, lang_code: str) -> int:
"""Traduit toutes les entrées non traduites dans un fichier .po."""
language_name = TARGET_LANGUAGES.get(lang_code)
if not language_name:
print(f"Code de langue non supporté : {lang_code}")
return 0
po = polib.pofile(po_path)
untranslated = po.untranslated_entries()
if not untranslated:
print(f"Pas d'entrées non traduites dans {po_path}")
return 0
print(f"Traduction de {len(untranslated)} entrées vers {language_name}...")
translated_count = 0
for entry in untranslated:
try:
entry.msgstr = translate_text(entry.msgid, language_name)
entry.flags.append("fuzzy") # Marquer comme nécessitant une vérification
translated_count += 1
except Exception as e:
print(f" Erreur lors de la traduction de '{entry.msgid[:50]}...' : {e}")
po.save()
print(f"{translated_count} entrées traduites dans {po_path}")
return translated_count
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage : python translate_po.py <chemin/django.po> <code_langue>")
sys.exit(1)
translate_po_file(sys.argv[1], sys.argv[2])
Exécutez-le :
python scripts/translate_po.py locale/es/LC_MESSAGES/django.po es python scripts/translate_po.py locale/fr/LC_MESSAGES/django.po fr
Traduction par Lot sur Tous les Locales
Pour les projets plus importants, un script par lot traite chaque locale en une seule fois :
# scripts/translate_all.py
from pathlib import Path
from translate_po import translate_po_file, TARGET_LANGUAGES
LOCALE_DIR = Path("locale")
def translate_all_locales():
"""Traduit les entrées non traduites pour tous les locales configurés."""
total = 0
for lang_code in TARGET_LANGUAGES:
po_path = LOCALE_DIR / lang_code / "LC_MESSAGES" / "django.po"
if po_path.exists():
count = translate_po_file(str(po_path), lang_code)
total += count
else:
print(f"Aucun fichier .po trouvé à {po_path}")
print(f"\nTotal des traductions : {total}")
if __name__ == "__main__":
translate_all_locales()
Flux de Travail de Vérification Qualité
Les entrées traduites par IA sont marquées avec le flag fuzzy, qui indique à Django (et aux réviseurs humains) que la traduction nécessite une vérification. C'est intentionnel et important :
- L'IA traduit — toutes les valeurs
msgstrnon traduites sont remplies et marquées commefuzzy - Les réviseurs vérifient — les locuteurs natifs vérifient les entrées fuzzy et suppriment le flag une fois approuvées
- Compiler — par défaut, seules les entrées non fuzzy sont incluses dans les fichiers
.mocompilés
Pour vérifier les entrées fuzzy :
# Compter les entrées fuzzy par locale
for lang in es fr de ja; do
count=$(grep -c "^#, fuzzy" locale/$lang/LC_MESSAGES/django.po 2>/dev/null || echo 0)
echo "$lang: $count entrées fuzzy"
done
Vous pouvez également utiliser des éditeurs de fichiers .po comme Poedit ou des plateformes web pour l'étape de vérification.
Pipeline CI/CD pour la Localisation Django
Automatiser le cycle extraire-traduire-compiler dans votre pipeline CI/CD garantit que les traductions restent synchronisées avec votre code.
Flux de Travail GitHub Actions
Voici un flux de travail GitHub Actions qui s'exécute à chaque push sur main :
# .github/workflows/i18n.yml
name: i18n Translation Pipeline
on:
push:
branches: [main]
paths:
- "**.py"
- "**.html"
- "locale/**"
jobs:
translate:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install dependencies
run: |
pip install -r requirements.txt
pip install polib openai
- name: Install gettext
run: sudo apt-get install -y gettext
- name: Extract messages
run: python manage.py makemessages --all --no-obsolete
- name: AI-translate new strings
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: python scripts/translate_all.py
- name: Compile messages
run: python manage.py compilemessages
- name: Commit translation updates
run: |
git config user.name "i18n-bot"
git config user.email "i18n-bot@users.noreply.github.com"
git add locale/
git diff --staged --quiet || git commit -m "chore(i18n): update translations"
git push
Décomposition du Pipeline
Le pipeline suit quatre étapes :
- Extraire —
makemessagesanalyse tous les fichiers Python et templates à la recherche de chaînes traduisibles nouvelles ou modifiées - Traduire — le script de traduction IA remplit toutes les entrées non traduites et les marque comme
fuzzy - Compiler —
compilemessagesgénère les fichiers binaires.mo - Commit — les modifications sont renvoyées au dépôt pour être disponibles lors du prochain déploiement
Pour les applications critiques en production, ajoutez une porte d'approbation manuelle entre les étapes de traduction et de compilation. Cela donne à votre équipe une fenêtre pour vérifier les traductions fuzzy avant qu'elles ne soient publiées.
Hook Pre-commit pour le Développement Local
Vous pouvez également ajouter un hook pre-commit pour détecter les traductions manquantes pendant le développement :
#!/bin/bash
# .git/hooks/pre-commit
# Vérifier les chaînes non traduites
python manage.py makemessages --all --no-obsolete 2>/dev/null
if git diff --name-only locale/ | grep -q ".po$"; then
echo "Avertissement : De nouvelles chaînes traduisibles ont été détectées."
echo "Exécutez 'python scripts/translate_all.py' pour les traduire."
fi
Comment Better i18n s'Intègre avec Django
Les scripts ci-dessus fonctionnent, mais ils nécessitent de maintenir du code de traduction personnalisé, de gérer les clés API, de gérer les limites de débit et de construire des flux de travail de vérification de zéro. Better i18n fournit une plateforme gérée qui gère l'ensemble du cycle de vie de traduction Django.
Voici comment Better i18n s'intègre dans un projet Django :
1. Synchroniser les fichiers .po avec Better i18n
Au lieu d'écrire des scripts d'analyse personnalisés, vous pouvez synchroniser vos fichiers .po directement avec Better i18n. La plateforme lit le format gettext nativement, mappant chaque paire msgid/msgstr aux clés de traduction.
2. Traduction IA avec flux de travail de vérification
Better i18n fournit une traduction IA intégrée spécifiquement adaptée à la localisation de logiciels. Les traductions passent par un flux de travail de vérification géré où les membres de l'équipe peuvent approuver, modifier ou rejeter les suggestions — sans outillage personnalisé.
3. Publier et récupérer les traductions
Une fois les traductions approuvées, vous pouvez les récupérer dans votre projet Django sous forme de fichiers .po mis à jour. L'étape de publication garantit que seules les traductions vérifiées atteignent votre base de code.
4. Intégration CI/CD
Le CLI de Better i18n peut remplacer les scripts personnalisés dans votre pipeline CI. Le cycle sync-translate-pull devient une seule commande dans votre flux de travail GitHub Actions.
Pour un aperçu plus approfondi des capacités i18n de Django, consultez notre guide du framework Django i18n. Si vous évaluez des outils de traduction pour votre flux de travail, notre guide des outils de traduction IA couvre le paysage actuel.
FAQ
Quelle est la différence entre i18n et l10n dans Django ?
L'internationalisation (i18n) est le processus de rendre votre application Django traduisible — marquer les chaînes, configurer le middleware, mettre en place les patterns URL. La localisation (l10n) est le processus de fournir réellement des traductions et un formatage spécifique au locale pour une langue et une région particulières. Dans Django, USE_I18N = True active le framework de traduction, tandis que USE_L10N = True active le formatage localisé des dates, nombres et calendriers.
Comment gérer la pluralisation dans Django ?
Django gère la pluralisation via la fonction ngettext() dans le code Python et la balise de template {% blocktrans count %}. Gettext prend en charge des règles de pluriel complexes — contrairement à l'anglais qui a deux formes (singulier/pluriel), des langues comme l'arabe ont six formes plurielles et le polonais en a trois. L'intégration gettext de Django gère tout cela via les définitions de forme plurielle dans l'en-tête du fichier .po.
Exemple Python :
from django.utils.translation import ngettext
def item_count_message(count):
return ngettext(
"You have %(count)d item.",
"You have %(count)d items.",
count,
) % {"count": count}
Exemple template :
{% load i18n %}
{% blocktrans count counter=notifications %}
You have {{ counter }} new notification.
{% plural %}
You have {{ counter }} new notifications.
{% endblocktrans %}
Puis-je utiliser l'IA pour traduire les fichiers .po Django ?
Oui. Les modèles de traduction IA peuvent analyser les fichiers .po et traduire les entrées msgstr en masse. L'approche recommandée est d'utiliser une bibliothèque comme polib pour lire les fichiers .po par programme, envoyer les chaînes non traduites à une API de traduction, réécrire les résultats avec un flag fuzzy, puis faire vérifier la sortie par des locuteurs natifs. Des outils comme Better i18n automatisent l'ensemble de ce pipeline, y compris le flux de travail de vérification, afin que vous n'ayez pas à maintenir des scripts personnalisés. La considération clé est de toujours marquer les traductions IA pour vérification humaine avant de les déployer en production.
