Automatiser les traductions Django avec DeepLr. Le guide complet

Django : automatiser les traductions avec Deeplr

Écrit par Fabien Schlegel

Fabien Schlegel

4 min

publié le : 06/03/2025

Django : automatiser les traductions avec Deeplr

Je n’ai jamais eu de traducteur sur les projets logiciels auxquels j’ai participé. Et pourtant, il a fallu ajouter des traductions. Et souvent, pour simplifier, j’avais les contenus en français et je traduisais moi même.

Grâce à Deeplr, c’est très simple, je colle mon contenu sur l’application et j’ai ma traduction.

Mais Deeplr fournit aussi une API et je vais te montrer comment l’utiliser pour automatiser les traductions simplement.

Préparer son projet Django pour l’internationalisation

Pour activer l’internationalisation avec Django, il suffit d’ajouter ce réglage dans le fichier settings.py

USE_I18N = True

Voici un exemple de chaînes de caractères marquées pour la traduction.

from django.apps import AppConfig
from django.utils.translation import gettext_lazy as _

class DashboardConfig(AppConfig):
    name = "dashboard"
    verbose_name = _("Dashboard")

Pour le code Python, on importe la méthode de traduction et on l’utilise sur la chaine à traduire.

{% load i18n %}
<h2 class="title has-text-centered">{% translate "Login" %}</h2>

Pour les gabarits, on ajoute le tag qui charge l’internationalisation et on mets les chaînes à traduire dans un tag translate.

Génération des fichiers de traductions

Pour générer les fichiers de traduction, il faut utiliser la commande intégrée à Django.

django-admin makemessages -l fr

Et fr est la langue pour laquelle vous allez générer les fichiers de traduction.

Configuration de l’API Deeplr

La clé API

Pour récupérer la clé API, il suffit d’aller sur le site de Deeplr et de créer un compte.

Une fois le compte créé, rendez vous dans le menu compte et clé API pour générer notre clé.

La librairie Python Deeplr

On va ensuite ajouter la librairie Deeplr à notre projet.

pip install deepl

Configuration dans Django

Il est vivement déconseillé de mettre la clé API directement dans notre fichier settings.py pour des questions de sécurité.

On va l’ajouter dans un fichier .env et l’importer dans notre fichiers de configuration grâce à la librairie decouple.

from decouple import config

DEEPL_API_KEY = config("DEEPL_API_KEY")

Automatisation des traductions

Méthode de traduction

import deepl

from django.conf import settings

translator = deepl.DeepLClient(settings.DEEPL_API_KEY)

def translate(text, target_lang):
    result = translator.translate_text(text, target_lang=target_lang)

    return result.text

On initialise une classe DeepLClient avec notre clé API et ensuite on utilise la méthode translate_text avec notre chaine à traduire et la langue cible.

La commande de traduction

Les fichiers de traduction Django utilisent l’extension .po on va donc utiliser la librairie polib pour les parcourir.

pip install polib

Grâce au système de commandes d’administration, on va créer une commande update_po pour mettre à jour nos traductions.

import os
from django.core.management.base import BaseCommand, CommandError
from core.translator import translate

from django.conf import settings

class Command(BaseCommand):
    help = "Met à jour les fichiers .po avec des traductions Deeplr"

    def add_arguments(self, parser):
        parser.add_argument(
            "-l", "--locale", type=str, help="Langue cible (ex: fr, de, es)"
        )

    def handle(self, *args, **options):
        try:
            if settings.DEBUG is False:
                raise Exception("Must be used in development only")

            import polib

            locale = options["locale"]
            base_dir = os.getcwd()

            for app in os.listdir(base_dir):
                locale_path = os.path.join(
                    base_dir, app, "locale", locale, "LC_MESSAGES"
                )
                po_file_path = os.path.join(locale_path, "django.po")
                if not os.path.exists(po_file_path):
                    continue

                po = polib.pofile(po_file_path)

                for entry in po:
                    if not entry.translated():
                        translated_text = translate(entry.msgid, locale)
                        entry.msgstr = translated_text
                        self.stdout.write(
                            self.style.SUCCESS(
                                f"[{app}] Traduit: {entry.msgid} -> {translated_text}"
                            )
                        )

                po.save()
                self.stdout.write(
                    self.style.SUCCESS(f"Mise à jour terminée pour {po_file_path}")
                )
        except Exception as e:
            print(e)
            raise CommandError("Error during translation")

Cette commande nous permet de mettre à jour une langue à la fois sur toute notre application. Par exemple ici en français.

python manage.py update_po --locale fr

Grâce à polib on parcourt nos fichiers .po qui contiennent les chaînes à traduire. Si une chaîne traduite est vide, on envoie la chaîne à traduire à Deeplr et on récupère le résultat.

Une fois toutes les chaînes du fichier traduites, on enregistre le fichier.

La librairie polib ne sera pas installée sur les environnements de production. C’est pour ça qu’elle est chargée dans la fonction handle , après un contrôle de la variable de configuration DEBUG et non pas au début du fichier.

Le pipeline de traduction

Django permet d’appeler des commandes d’administration dans une commande. Ce qui nous permet de réaliser toute la chaîne d’une coup pour une langue donnée.

  • makemessages : On mets à jour les fichiers de chaînes à traduire
  • update_po : On traduit les ajouts
  • compilemessages : On compile les traductions
python manage.py make_translations --lang fr

Voici le fichier de commande.

from django.core.management.base import BaseCommand, CommandError

from django.core.management import call_command

class Command(BaseCommand):
    help = "Mise à jour complète des traductions"

    def add_arguments(self, parser):
        parser.add_argument(
            "-l", "--lang", type=str, help="Langue cible (ex: fr, de, es)"
        )

    def handle(self, *args, **options):
        try:
            lang = options["lang"]

            self.stdout.write(self.style.WARNING("Execute makemessages"))
            call_command("makemessages", locale=[lang])
            self.stdout.write(self.style.SUCCESS(f"makemessages done for {lang}."))

            self.stdout.write(self.style.WARNING("Update translations..."))
            call_command("update_po", locale=lang)
            self.stdout.write(self.style.WARNING("Translations updated"))

            self.stdout.write(
                self.style.WARNING("Start compiling translations")
            )
            call_command("compilemessages")
            self.stdout.write(self.style.SUCCESS("Compilation is complete."))
        except Exception as e:
            print(e)
            raise CommandError("Error during translation")

Conclusion

Grâce à ce système il devient plus facile de traduire notre application dans d’autres langues de manière automatisée.

Ca ne remplace pas un vrai traducteur bien évidemment. J’ai eu quelques surprises en parcourant les traductions mais dans l’ensemble ça couvre mes besoins.

Articles associés