Las cadenas de traducción especifican "Este texto debería ser traducido." dichas cadenas pueden aparecer en tu código Python y en tus plantillas. Es tú responsabilidad marcar las cadenas traducibles; el sistema sólo puede traducir cadenas sobre las que está al tanto.
18.1.1. Funciones estándar de traducción
Las cadenas de traducción se especifican usando la función _()
. (Si, el
nombre de la función es el carácter guión bajo). Esta función está disponible
globalmente (o sea como un componente incluido); no es necesario que lo
importes.
En este ejemplo, el texto "Welcome to my site."
está marcado como una
cadena de traducción:
def my_view(request):
output = _("Welcome to my site.")
return HttpResponse(output)
La función django.utils.translation.gettext()
es idéntica a _()
. Este
ejemplo es idéntico al anterior:
from django.utils.translation import gettext
def my_view(request):
output = gettext("Welcome to my site.")
return HttpResponse(output)
La mayoría de los desarrolladores prefiere usar _()
, debido a que es más
corta.
La traducción funciona también sobre valores computados. Este ejemplo es idéntico a los dos anteriores:
def my_view(request):
words = ['Welcome', 'to', 'my', 'site.']
output = _(' '.join(words))
return HttpResponse(output)
La traducción funciona también sobre variables. De nuevo, este es otro ejemplo idéntico:
def my_view(request):
sentence = 'Welcome to my site.'
output = _(sentence)
return HttpResponse(output)
(algo a tener en cuenta cuando se usan variables o valores computados, como se
veía en los dos ejemplos previos, es que la utilidad de detección de cadenas de
traducción de Django, make-messages.py
, no será capaz de encontrar esas
cadenas. Trataremos make-messages
más adelante).
Las cadenas que le pasas a _()
o gettext()
pueden contener marcadores de
posición (por placeholders), especificados con la sintaxis estándar de
interpolación de cadenas con nombres, por ejemplo:
def my_view(request, n):
output = _('%(name)s is my name.') % {'name': n}
return HttpResponse(output)
Esta técnica permite que las traducciones específicas de cada idioma reordenen
el texto de los marcadores de posición. Por ejemplo, una traducción al inglés
podría ser Adrian is my name
, mientras que una traducción al español podría
ser Me llamo Adrian
, con el marcador de posición (el nombre) ubicado a
continuación del texto traducido y no antes del mismo.
Por esta razón, deberías usar interpolación de cadenas con nombres (por ejemplo
%(name)s
) en lugar de interpolación posicional (por ejemplo %s
o
%d
). Si usas interpolación posicional las traducciones no serán capaces de
reordenar el texto de los marcadores de posición.
18.1.2. Marcando cadenas como no-op
Usa la función django.utils.translation.gettext_noop()
para marcar una
cadena como una cadena de traducción sin realmente traducirla en ese momento.
Las cadenas así marcadas no son traducidas sino hasta el último momento que
sea posible.
Usa este enfoque si deseas tener cadenas constantes que deben ser almacenadas en el idioma original — tales como cadenas en una base de datos — pero que deben ser traducidas en el último momento posible, por ejemplo cuando la cadena es presentada al usuario.
18.1.3. Traducción perezosa
Usa la función django.utils.translation.gettext_lazy()
para traducir cadenas
en forma perezosa — cuando el valor es accedido en lugar de cuando se llama a
la función gettext_lazy()
.
Por ejemplo, para marcar el atributo help_text
de un campo como traducible,
haz lo siguiente:
from django.utils.translation import gettext_lazy
class MyThing(models.Model):
name = models.CharField(help_text=gettext_lazy('This is the help text'))
En este ejemplo, gettext_lazy()
almacena una referencia perezosa a la cadena
— no el verdadero texto traducido. La traducción en si misma se llevará a cabo
cuando sea usada en un contexto de cadena, tal como el renderizado de una
plantilla en el sitio de administración de Django.
Si no te gusta el nombre largo gettext_lazy
puedes simplemente crear un
alias _
(guión bajo) para el mismo, de la siguiente forma:
from django.utils.translation import gettext_lazy as _
class MyThing(models.Model):
name = models.CharField(help_text=_('This is the help text'))
Usa siempre traducciones perezosas en modelos Django (de lo contrario no serán
traducidos correctamente para cada usuario). Y es una buena idea agregar
también traducciones de los nombres de campos y nombres de tablas. Esto
significa escribir las opciones verbose_name
y verbose_name_plural
en forma
explícita en la clase Meta
:
from django.utils.translation import gettext_lazy as _
class MyThing(models.Model):
name = models.CharField(_('name'), help_text=_('This is the help text'))
class Meta:
verbose_name = _('my thing')
verbose_name_plural = _('mythings')
18.1.4. Pluralización
Usa la función django.utils.translation.ngettext()
para especificar mensajes
que tienen formas singular y plural distintas, por ejemplo:
from django.utils.translation import ngettext
def hello_world(request, count):
page = ngettext(
'there is %(count)d object',
'there are %(count)d objects', count
) % {'count': count}
return HttpResponse(page)
ngettext
tiene tres argumentos: la cadena de traducción singular, la
cadena de traducción plural y el número de objetos (el cual es pasado a los
idiomas de traducción como la variable count
).