Quand dois-je utiliser ugettext_lazy?

141

J'ai une question sur l'utilisation de ugettext et ugettext_lazypour les traductions. J'ai appris que dans les modèles je devrais utiliser ugettext_lazy, tandis que dans les vues ugettext. Mais y a-t-il d'autres endroits où je devrais ugettext_lazyaussi utiliser ? Qu'en est-il des définitions de formulaire? Y a-t-il des différences de performances entre eux?

Edit: Et encore une chose. Parfois, au lieu de ugettext_lazy, ugettext_noopest utilisé. Comme le dit la documentation, les ugettext_noopchaînes ne sont marquées pour la traduction et traduites que le plus tard possible avant de les afficher à l'utilisateur, mais je suis un peu confus ici, n'est-ce pas similaire à quoi ugettext_lazyfaire? J'ai encore du mal à décider lequel utiliser dans mes modèles et mes formulaires.

Dzejkob
la source

Réponses:

197

ugettext() contre. ugettext_lazy()

Dans les définitions comme les formulaires ou les modèles, vous devriez utiliser ugettext_lazycar le code de ces définitions n'est exécuté qu'une seule fois (principalement au démarrage de django); ugettext_lazytraduit les chaînes de manière paresseuse, ce qui signifie, par exemple. chaque fois que vous accédez au nom d'un attribut sur un modèle, la chaîne sera nouvellement traduite - ce qui est tout à fait logique car vous pourriez regarder ce modèle dans différentes langues depuis le démarrage de django!

Dans les vues et les appels de fonctions similaires, vous pouvez les utiliser ugettextsans problème, car chaque fois que la vue est appelée ugettextsera nouvellement exécutée, vous obtiendrez donc toujours la bonne traduction correspondant à la demande!

En ce qui concerne ugettext_noop()

Comme Bryce l'a souligné dans sa réponse, cette fonction marque une chaîne comme extractible pour la traduction mais renvoie la chaîne non traduite. Ceci est utile pour utiliser la chaîne à deux endroits - traduite et non traduite. Consultez l'exemple suivant:

import logging
from django.http import HttpResponse
from django.utils.translation import ugettext as _, ugettext_noop as _noop

def view(request):
    msg = _noop("An error has occurred")
    logging.error(msg)
    return HttpResponse(_(msg))
Bernhard Vallant
la source
16
C'est plus compréhensible que l'explication de la documentation de Django à mon avis. Merci @Bernhard.
Utku
14
Merci! Il serait également utile d'expliquer quand ne pas utiliser ugettext_lazy, par exemple lorsque vous le passez à des éléments qui attendent une chaîne comme "" .replace, la concaténation de chaînes et autres; un objet proxy paresseux ne fonctionnera pas dans ces cas. Sinon, cette réponse implique que vous êtes en sécurité en utilisant toujours ugettext_lazy.
mrooney
4
@mrooney, ces cas importent moins car ils vous donneront une erreur si vous les faites, au lieu de renvoyer silencieusement la mauvaise traduction dans la langue. De plus, vous pouvez utiliser "" .replace avec ugettext_lazy, il vous suffit d'appeler str () sur le résultat, par exemple lazytext = ugettext_lazy ('hello') et plus tard, utilisez str (lazytext) .replace.
fabspro
1
qu'en est-il de msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop ?si sans _noop, django ne trouve pas la chaîne à traduire?
WeizhongTu
1
La traduction fonctionne sur des variables. Encore une fois, voici un exemple de documentation identique , alors pourquoi _noop?
WeizhongTu
17

Une excellente utilisation de _noop, est lorsque vous souhaitez enregistrer un message en anglais pour les développeurs, mais présenter la chaîne traduite à un visualiseur. Un exemple de ceci est à http://blog.bessas.me/posts/using-gettext-in-django/

Bryce
la source
4
Le lien est rompu…
nalzok
5

La version différée renvoie un objet proxy au lieu d'une chaîne et dans certaines situations, cela ne fonctionnerait pas comme prévu. Par exemple:

def get(self, request, format=None):
   search_str = request.GET.get('search', '')
   data = self.search(search_str)
   lst = []
   lst.append({'name': ugettext_lazy('Client'), 'result': data})
   return HttpResponse(json.dumps(lst), content_type='application/json')

échouerait parce que la toute dernière ligne essaierait de sérialiser l' objet lst en JSON et au lieu d'une chaîne pour "client", il aurait un objet proxy. L'objet proxy n'est pas sérialisable dans json.

Alex Protyagov
la source
2
Vous devez utiliser ugettext dans ces cas.
sudip