Aller au contenu

Django et la traduction

gettext() vs ugettext()

Depuis Django 2.0, il s'agit de synonymes.

Voici ce que l'on trouve dans le code source de Django 2.2 :

# An alias since Django 2.0
ugettext = gettext

et un peu plus bas :

gettext_lazy = ugettext_lazy = lazy(gettext, str)

gettext() vs gettext_lazy()

Dans le code source de Django 3.2 :

gettext_lazy = lazy(gettext, str)

Réponse intéressante notée dans python - When should I use ugettext_lazy? - Stack Overflow :

In definitions like forms or models you should use ugettext_lazy because the code of this definitions is only executed once (mostly on django's startup); ugettext_lazy translates the strings in a lazy fashion, which means, eg. every time you access the name of an attribute on a model the string will be newly translated-which totally makes sense because you might be looking at this model in different languages since django was started!

In views and similar function calls you can use ugettext without problems, because everytime the view is called ugettext will be newly executed, so you will always get the right translation fitting the request!

En résumé

On n'utilise plus ugettext() et ugettext_lazy(), et on utilise gettext() ou gettext_lazy() en fonction des cas.

Contrairement à gettext(), gettext_lazy() permet de traduire du texte en différé, au moment où la chaîne est réellement utilisée plutôt qu’au moment où la fonction est appelée.

Cas d'utilisation de gettext() ou gettext_lazy() :

gettext() gettext_lazy()
views
validators
admin
signal
models
form
apps
settings
context_processors

Pour importer ugettext() (ou ugettext_lazy()) on utilise l'alias _ :

from django.utils.translation import gettext as _
from django.utils.translation import gettext_lazy as _

Créer et modifier les fichiers de langues

Exemple avec une application fictive foo à laquelle on souhaite ajouter les traductions de l'interface en français.

Se placer dans le répertoire de l'application foo et créer le dossier locale (s'il n'existe pas encore) :

$ cd apps/foo/
$ mkdir -p locale

Pour créer ou mettre à jour un fichier de messages en français, exécutez la commande :

$ ../../venv/bin/django-admin makemessages -l fr

Editez le fichier locale/fr/LC_MESSAGES/django.po créé et compilez le fichier .po en un fichier .mo :

$ ../../venv/bin/django-admin compilemessages

Traduction des modèles

Il est quelquefois nécessaire de traduire des champs de modèle. Pour ce faire, on utilise la librairie django-modeltranslation.

Par exemple, voir la traduction des champs bar et qix de la classe Foo de l'application foo suivante :

# /apps/foo/translation.py
import simple_history
from modeltranslation.translator import translator, TranslationOptions
from foo.models import Foo


class FooTranslationOptions(TranslationOptions):
    fields = ("bar", "qix")


translator.register(Foo, FooTranslationOptions)
simple_history.register(Foo)

Warning

Attention aux interactions entre les librairies django-modeltranslation et django-simple-history !

Ne pas utiliser history = HistoricalRecords() dans un modèle lorsque celui-ci comporte des champs marqués par django-modeltranslation, mais utiliser plutôt le fichier translation.py dans lequel on peut référencer un objet après avoir configuré la traduction.

Toujour avec l'exemple précédent :

translator.register(Foo, FooTranslationOptions)
simple_history.register(Foo)

Ressources