¿Cuándo debo usar ugettext_lazy?

141

Tengo una pregunta sobre el uso de ugettext y ugettext_lazypara las traducciones. Aprendí que en los modelos debería usar ugettext_lazy, mientras que en las vistas ugettext. ¿Pero hay otros lugares, donde debería usar ugettext_lazytambién? ¿Qué pasa con las definiciones de formulario? ¿Hay alguna diferencia de rendimiento entre ellos?

Editar: Y una cosa más. A veces, en lugar de ugettext_lazy, ugettext_noopse usa. Como dice la documentación, las ugettext_noopcadenas solo están marcadas para traducción y traducidas al último momento posible antes de mostrarlas al usuario, pero estoy un poco confundido aquí, ¿no es eso similar a qué ugettext_lazyhacer? Todavía es difícil para mí decidir qué debo usar en mis modelos y formularios.

Dzejkob
fuente

Respuestas:

196

ugettext() vs. ugettext_lazy()

En definiciones como formularios o modelos, debe usar ugettext_lazyporque el código de estas definiciones solo se ejecuta una vez (principalmente en el inicio de django); ugettext_lazytraduce las cadenas de forma perezosa, lo que significa, por ejemplo. cada vez que acceda al nombre de un atributo en un modelo, la cadena se traducirá recientemente, lo que tiene mucho sentido porque puede estar viendo este modelo en diferentes idiomas desde que se inició django.

En vistas y llamadas de funciones similares, puede usar ugettextsin problemas, porque cada vez que se llama a la vista se ugettextejecutará nuevamente, por lo que siempre obtendrá la traducción correcta que se ajuste a la solicitud.

Respecto a ugettext_noop()

Como Bryce señaló en su respuesta, esta función marca una cadena como extraíble para la traducción, pero devuelve la cadena no traducida. Esto es útil para usar la cadena en dos lugares: traducido y no traducido. Vea el siguiente ejemplo:

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
fuente
15
Eso es más comprensible que la explicación en la documentación de Django en mi opinión. Gracias @ Bernhard.
Utku
14
¡Gracias! También sería útil explicar cuándo no usar ugettext_lazy, como cuando se pasa a cosas que esperan una cadena como "" .replace, concatenación de cadenas y otras; un objeto proxy diferido no funcionará en esos casos. De lo contrario, esta respuesta implica que estás seguro solo usando ugettext_lazy.
mrooney
44
@mrooney esos casos importan menos porque te darán un error si los haces, en lugar de devolver en silencio la traducción incorrecta del idioma. Además, puede usar "" .replace con ugettext_lazy, solo tiene que llamar a str () en el resultado, por ejemplo, lazytext = ugettext_lazy ('hola') y luego usar str (lazytext) .replace.
fabspro
1
¿Qué pasa con msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop ?si sin _noop, django no encuentra que la cadena necesita traducción?
WeizhongTu
1
La traducción funciona en variables. De nuevo, aquí hay un ejemplo idéntico de documentos , ¿por qué _noop?
WeizhongTu
5

La versión diferida devuelve un objeto proxy en lugar de una cadena y en alguna situación no funcionaría como se esperaba. Por ejemplo:

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')

fallaría porque la última línea intentaría serializar el objeto lst en JSON y en lugar de una cadena para "cliente" tendría un objeto proxy. El objeto proxy no se puede serializar en json.

Alex Protyagov
fuente
2
Debería usar ugettext en estos casos.
sudip