¿Dónde usar “gettext_lazy ()” en Django?

5 minutos de lectura

Avatar de usuario de Dzejkob
Dzejkob

Tengo una pregunta sobre el uso de ugettext y gettext_lazy() para traducciones. Aprendí que en los modelos debo usar gettext_lazy(), mientras que en las vistas ugettext. Pero, ¿hay otros lugares donde debería usar gettext_lazy() ¿tambié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 gettext_lazy(), gettext_noop() se usa Como dice la documentación, gettext_noop() las cadenas solo se marcan para la traducción y se traducen en el último momento posible antes de mostrárselas al usuario, pero estoy un poco confundido aquí, ¿no es similar a lo que gettext_lazy() ¿hacer? Todavía es difícil para mí decidir cuál debo usar en mis modelos y formularios.

Avatar de usuario de Bernhard Vallant
bernhard valent

gettext() contra gettext_lazy()

En definiciones como formularios o modelos, debe usar gettext_lazy porque el código de estas definiciones solo se ejecuta una vez (principalmente en el inicio de Django); gettext_lazy traduce 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á nuevamente, lo que tiene mucho sentido porque es posible que esté viendo este modelo en diferentes idiomas desde que se inició Django.

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

Acerca de gettext_noop()

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

import logging
from django.http import HttpResponse
from django.utils.translation import gettext as _, gettext_noop as _noop

def view(request):
    msg = _noop("An error has occurred")
    logging.error(msg)
    return HttpResponse(_(msg))

  • En mi opinión, eso es más comprensible que la explicación en la documentación de Django. Gracias @Bernhard.

    – Utku

    2 de agosto de 2012 a las 23:01

  • ¡Gracias! También sería útil explicar cuándo no para usar ugettext_lazy, como cuando se pasa a elementos que esperan una cadena como “”.replace, concatenación de cadenas y otros; un objeto proxy perezoso no funcionará en esos casos. De lo contrario, esta respuesta implica que está seguro siempre usando ugettext_lazy.

    – mooney

    26 de febrero de 2013 a las 21:08

  • @mrooney, esos casos importan menos porque le darán un error si los hace, en lugar de devolver silenciosamente la traducción incorrecta del idioma. Además, puede usar “”.reemplazar con ugettext_lazy, solo tiene que llamar a str() en el resultado, por ejemplo, lazytext=ugettext_lazy(‘hello’) y luego usar str(lazytext).replace.

    – fabspro

    1 de marzo de 2014 a las 10:49

  • qué pasa msg = "An error has occurred"; logging.error(msg);return HttpResponse(_(msg))? why need _noop? si sin _noopdjango no encontrará la cadena que necesita traducción?

    – Weizhong Tu

    7 sep 2016 a las 12:16


  • Para su información, descubrí que si importa una de las funciones de marcado (por ejemplo, ugettext) como _y luego importar un segundo (por ejemplo ugettext_noop) usando import as (p.ej import ugettext_noop as _noop), entonces xgettext no reconocerá y extraerá este último. En otras palabras, todas las importaciones que no sean la que usted import as _ deben ser importados y referenciados por su nombre completo.

    –Eric P

    4 de diciembre de 2018 a las 18:41

Avatar de usuario de Bryce
bryce

Un excelente uso de _noop es cuando desea registrar un mensaje en inglés para los desarrolladores, pero presentar la cadena traducida a un espectador. Un ejemplo de esto está en http://blog.bessas.me/posts/using-gettext-in-django/

  • El enlace está roto…

    – nalzok

    29 de marzo de 2017 a las 2:38

La versión perezosa devuelve un objeto proxy en lugar de una cadena y, en algunas situaciones, 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 primero objeto en JSON y en lugar de una cadena para “cliente” tendría un objeto proxy. El objeto proxy no se puede serializar en json.

  • Debe usar ugettext en estos casos.

    – sorber

    11 de mayo de 2016 a las 12:13

Super Kai - Avatar de usuario de Kazuya Ito
Súper Kai – Kazuya Ito

obtenertexto() puede funcionar dentro de funciones pero no funciona fuera de funciones.

gettext_lazy() Puede trabajar dentro y fuera de las funciones.

*Será mejor que uses gettext_lazy() funciones externas de acuerdo con los ejemplos de Traducción.

Esto de abajo es donde gettext() puede trabajar:

# "my_app1/views.py"

from django.http import HttpResponse
from django.utils.translation import gettext as _

def hello(request):
    HttpResponse(_("Hello")) # Here

Esto de abajo es donde gettext_lazy() puede trabajar:

# "core/settings.py"

from django.utils.translation import gettext_lazy as _

LANGUAGES = (
    ('en', _('English')),
    ('fr', _('French'))
)
# "my_app1/views.py"

from django.http import HttpResponse
from django.utils.translation import gettext_lazy as _

def hello(request): # Here
    HttpResponse(_("Hello"))
# "my_app1/urls.py"

from django.urls import path
from . import views
from django.utils.translation import gettext_lazy as _

app_name = "my_app1"

urlpatterns = [
    path(_('hello'), views.hello, name="hello"),
]        # Here
# "my_app1/models.py"

from django.db import models
from django.utils.translation import gettext_lazy as _

class Person(models.Model):                             # Here
    name = models.CharField(max_length=20, verbose_name=_("name"))

    class Meta:
        verbose_name = _('person') # Here
        verbose_name_plural = _('persons') # Here
# "my_app1/admin.py"

from django.contrib import admin
from django import forms
from .models import Person
from django.utils.translation import gettext_lazy as _

admin.site.site_title = _('My site title') # Here
admin.site.site_header = _('My site header') # Here
admin.site.index_title = _('My index title') # Here

class PersonForm(forms.ModelForm): # Here
    name = forms.CharField(label=_('name')) 

    class Meta:
        model = Person
        fields = "__all__"

@admin.register(Person)
class PersonAdmin(admin.ModelAdmin):    
    form = PersonForm
# "my_app1/apps.py"

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

class App1Config(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name="my_app1"
    verbose_name = _('my app1') # Here

¿Ha sido útil esta solución?