El lenguaje de plantillas de Django

Este documento explica la sintaxis del lenguaje de plantillas del sistema de plantillas de Django. Si estás buscando una perspectiva más técnica sobre cómo funciona y cómo extenderlo, vea El lenguaje de plantillas Django: para programadores de Python.

El lenguaje de plantillas de Django está diseñado para encontrar un equilibrio entre potencia y facilidad. Está diseñado para sentirse cómodo a aquellos que están acostumbrados a trabajar con HTML. Si tienes alguna experiencia con otros lenguajes de plantillas basadas en texto, como Smarty o Jinja2, deberías sentirte a gusto con las plantillas de Django.

Filosofía

Si tienes un fondo en programación, o si estás acostumbrado a lenguajes que mezclan código de programación directamente con HTML, querrás tener en cuenta que el sistema de plantillas de Django no es simplemente Python insertado en HTML. Esto está diseñado: el sistema de plantillas está destinado a expresar la presentación, no la lógica del programa.

El sistema de plantillas de Django proporciona etiquetas que funcionan de manera similar a algunas construcciones de programación – una if etiqueta para pruebas booleanas, una for etiqueta para bucles, etc. – pero estas no son simplemente ejecutadas como el código Python correspondiente, y el sistema de plantillas no ejecutará expresiones Python arbitrarias. Solo las etiquetas, filtros y sintaxis listados a continuación están soportados por defecto (aunque puedes agregar extensiones personalizadas al lenguaje de plantillas según sea necesario).

Plantillas

Una plantilla es un archivo de texto. Puede generar cualquier formato basado en texto (HTML, XML, CSV, etc.).

Una plantilla contiene variables, que se reemplazan con valores cuando la plantilla se evalúa, y etiquetas, que controlan la lógica de la plantilla.

A continuación está una plantilla mínima que ilustra algunos conceptos básicos. Cada elemento se explicará más adelante en este documento.

{% extends "base_generic.html" %}

{% block title %}{{ section.title }}{% endblock %}

{% block content %}
<h1>{{ section.title }}</h1>

{% for story in story_list %}
<h2>
  <a href="{{ story.get_absolute_url }}">
    {{ story.headline|upper }}
  </a>
</h2>
<p>{{ story.tease|truncatewords:"100" }}</p>
{% endfor %}
{% endblock %}

Filosofía

Por qué usar un plantilla basada en texto en lugar de una basada en XML (como la TAL de Zope)? Queríamos que el lenguaje de plantillas de Django fuera usable para más que solo plantillas XML/HTML. Puedes utilizar el lenguaje de plantillas para cualquier formato de texto como correos electrónicos, JavaScript y CSV.

Variables

Las variables se ven así: {{ variable }}. Cuando el motor de plantillas encuentra una variable, evalúa esa variable y la reemplaza con el resultado. Los nombres de las variables consisten en cualquier combinación de caracteres alfanuméricos y el guión bajo ("_") pero no pueden empezar con un guión bajo ni ser un número. El punto (".") también aparece en secciones de variable, aunque tiene un significado especial, como se indica a continuación. Importancia: no puedes tener espacios o caracteres de puntuación en los nombres de las variables.

Utiliza un punto (.) para acceder a atributos de una variable.

Detrás de escena

Técnicamente, cuando el sistema de plantillas encuentra un punto, intenta las siguientes consultas, en este orden:

  • Consulta de diccionario

  • Consulta de atributo o método

  • Consulta de índice numérico

Si el valor resultante es llamable, se llama con ningún argumento. El resultado de la llamada se convierte en el valor de plantilla.

Este orden de consulta puede causar comportamientos inesperados con objetos que sobreescriben la consulta de diccionario. Por ejemplo, considera el siguiente fragmento de código que intenta recorrer una collections.defaultdict:

{% for k, v in defaultdict.items %}
    Do something with k and v here...
{% endfor %}

Porque la búsqueda en el diccionario ocurre primero, ese comportamiento se activa y proporciona un valor por defecto en lugar de utilizar el método .items() previsto. En este caso, considera convertir a un diccionario primero.

En el ejemplo anterior, {{ section.title }} se reemplazará con la propiedad title del objeto section.

Si utilizas una variable que no existe, el sistema de plantillas insertará el valor de la opción string_if_invalid, que está configurada por defecto en '' (la cadena vacía).

Ten en cuenta que «bar» en una expresión de plantilla como {{ foo.bar }} se interpretará como una cadena literal y no utilizará el valor de la variable «bar», si existe en el contexto de la plantilla.

Las propiedades de las variables que comienzan con un guión bajo pueden no ser accesibles ya que se consideran privadas.

Filtros

Puedes modificar las variables para su visualización utilizando filtros.

Los filtros tienen este aspecto: {{ name|lower }}. Esto muestra el valor de la variable {{ name }} después de ser filtrado a través del filtro lower, que convierte el texto a minúsculas. Utiliza una barra vertical (|) para aplicar un filtro.

Los filtros pueden «enlazarse». El resultado de uno se aplica al siguiente. {{ text|escape|linebreaks }} es un idiolecto común para escapar el contenido del texto, luego convertir las interlíneas a etiquetas <p>.

Algunos filtros aceptan argumentos. Un argumento de filtro tiene este aspecto: {{ bio|truncatewords:30 }}. Esto mostrará las primeras 30 palabras de la variable bio.

Los argumentos de los filtros que contienen espacios deben estar citados; por ejemplo, para unir una lista con comas y espacios utilizarías {{ list|join:", " }}.

Django proporciona unos sesenta filtros de plantilla integrados. Puedes leer más sobre ellos en la referencia de los filtros integrados. Para darte una idea de lo que está disponible, aquí tienes algunos de los filtros de plantilla más utilizados:

por defecto

Si una variable es falsa o vacía, utiliza el valor por defecto dado. De lo contrario, utilice el valor de la variable. Por ejemplo:

{{ value|default:"nothing" }}

Si no se proporciona value o está vacío, el texto anterior mostrará nothing.

longitud

Devuelve la longitud del valor. Esto funciona tanto para cadenas como para listas. Por ejemplo:

{{ value|length }}

Si value es ['a', 'b', 'c', 'd'], el resultado será 4.

formato de tamaño de archivo

Formatea el valor como un «tamaño de archivo legible por humanos» (es decir, '13 KB', '4.1 MB', '102 bytes', etc.). Por ejemplo:

{{ value|filesizeformat }}

Si value es 123456789, la salida sería 117.7 MB.

Otra vez, estos son solo unos ejemplos; para ver la lista completa, consulta el referencia de filtros integrados.

También puedes crear tus propios filtros de plantilla personalizados; consulta Cómo crear etiquetas y filtros de plantilla personalizados.

Ver también

La interfaz de administración de Django puede incluir una referencia completa de todos los marcadores y filtros de plantilla disponibles para un sitio determinado. Consulta la documentación en La documentación generadora del administrador Django.

Tags

Etiquetas parecen ser esto: {% tag %}. Las etiquetas son más complejas que las variables: Algunas crean texto en la salida, algunas controlan el flujo mediante bucles o lógica y otras cargan información externa en el template para que sea utilizada por variables posteriores.

Algunos etiquetas requieren una etiqueta de inicio y una etiqueta de fin (es decir, `{% tag %} ... contenido de la etiqueta ... {% endtag %}).

Django viene con unos dos docenas de etiquetas de plantilla integradas. Puedes leer más sobre ellas en la referencia de las etiquetas integradas. Para darte una idea de lo que está disponible, aquí tienes algunas de las etiquetas más comúnmente utilizadas:

for

Recorre cada elemento en un arreglo. Por ejemplo, para mostrar una lista de atletas proporcionada en athlete_list:

<ul>
{% for athlete in athlete_list %}
    <li>{{ athlete.name }}</li>
{% endfor %}
</ul>
ttag:`if, elif, y else

Evalúa una variable, y si esa variable es «verdadero», se muestra el contenido del bloque:

{% if athlete_list %}
    Number of athletes: {{ athlete_list|length }}
{% elif athlete_in_locker_room_list %}
    Athletes should be out of the locker room soon!
{% else %}
    No athletes.
{% endif %}

En la sección anterior, si athlete_list no está vacío, el número de atletas se mostrará mediante la variable {{ athlete_list|length }}. De lo contrario, si athlete_in_locker_room_list no está vacío, se mostrará el mensaje «Los atletas deben estar fuera…». Si ambos listados están vacíos, se mostrará «No hay atletas.».

Puedes utilizar también filtros y operadores variados en la etiqueta if:

{% if athlete_list|length > 1 %}
   Team: {% for athlete in athlete_list %} ... {% endfor %}
{% else %}
   Athlete: {{ athlete_list.0.name }}
{% endif %}

Si bien el ejemplo anterior funciona, ten en cuenta que la mayoría de los filtros de plantilla devuelven cadenas, por lo que las comparaciones matemáticas utilizando filtros no funcionarán como esperas. length es una excepción.

block y extends

Configura la herencia de plantilla (consulte a continuación), una forma poderosa de reducir el «boilerplato» en las plantillas.

De nuevo, lo anterior solo es una selección de la lista completa; consulta la referencia de etiquetas de plantilla integradas <ref-templates-builtins-tags> para obtener la lista completa.

Puedes crear también tus propias etiquetas de plantilla personalizadas; consulta Cómo crear etiquetas y filtros de plantilla personalizados.

Ver también

La interfaz de administración de Django puede incluir una referencia completa de todos los marcadores y filtros de plantilla disponibles para un sitio determinado. Consulta la documentación en La documentación generadora del administrador Django.

Comentarios

Para comentar una parte de una línea en una plantilla, utiliza el síntaxis de comentario: {# #}.

Por ejemplo, esta plantilla se renderizaría como 'hello':

{# greeting #}hello

Un comentario puede contener cualquier código de plantilla, válido o no. Por ejemplo:

{# {% if foo %}bar{% else %} #}

Esta sintaxis solo se puede utilizar para comentarios de una sola línea (no se permiten nuevas líneas entre los delimitadores {# y #}. Si necesitas comentar una porción multilinea de la plantilla, consulta el comment tag.

Herencia de plantillas

La parte más poderosa – y, por lo tanto, la más compleja – del motor de plantillas de Django es la herencia de plantillas. La herencia de plantillas permite construir una base «esqueleto» que contiene todos los elementos comunes de tu sitio y define bloques que las plantillas hijas pueden sobrescribir.

Vamos a ver la herencia de plantillas empezando con un ejemplo:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <title>{% block title %}My amazing site{% endblock %}</title>
</head>

<body>
    <div id="sidebar">
        {% block sidebar %}
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
        {% endblock %}
    </div>

    <div id="content">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

Esta plantilla, que llamaremos base.html, define un documento HTML esqueleto que podrías utilizar para una página en dos columnas. Es el trabajo de las «plantillas hijas» llenar los bloques vacíos con contenido.

En este ejemplo, la etiqueta block define tres bloques que las plantillas hijas pueden rellenar. Todo lo que hace la etiqueta block es decirle al motor de plantillas que una plantilla hija puede sobrescribir esas partes de la plantilla.

Una plantilla hija podría verse así:

{% extends "base.html" %}

{% block title %}My amazing blog{% endblock %}

{% block content %}
{% for entry in blog_entries %}
    <h2>{{ entry.title }}</h2>
    <p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}

La etiqueta extends es la clave aquí. Le dice al motor de plantillas que esta plantilla «extiende» otra plantilla. Cuando el sistema de plantillas evalúa esta plantilla, primero localiza a la madre – en este caso, base.html.

En ese punto, el motor de plantillas notará los tres etiquetas block en base.html y reemplazará esos bloques con el contenido de la plantilla hija. Dependiendo del valor de blog_entries, el resultado podría ser:

<!DOCTYPE html>
<html lang="en">
<head>
    <link rel="stylesheet" href="style.css">
    <title>My amazing blog</title>
</head>

<body>
    <div id="sidebar">
        <ul>
            <li><a href="/">Home</a></li>
            <li><a href="/blog/">Blog</a></li>
        </ul>
    </div>

    <div id="content">
        <h2>Entry one</h2>
        <p>This is my first entry.</p>

        <h2>Entry two</h2>
        <p>This is my second entry.</p>
    </div>
</body>
</html>

Ten en cuenta que ya que la plantilla hija no definió el bloque sidebar, se utiliza el valor de la plantilla padre en su lugar. El contenido dentro de un tag {% block %} en una plantilla padre siempre se utiliza como fallback.

Puedes utilizar tantos niveles de herencia como necesites. Una forma común de utilizar la herencia es el siguiente enfoque de tres niveles:

  • Crea un archivo base.html que contenga el aspecto visual principal de tu sitio.

  • Crea un archivo base_SECTIONNAME.html para cada «sección» de tu sitio. Por ejemplo, base_news.html, base_sports.html. Estos archivos extienden base.html y incluyen estilos/diseño específicos de la sección.

  • Crea plantillas individuales para cada tipo de página, como un artículo de noticias o una entrada en el blog. Estas plantillas extienden la plantilla correspondiente a la sección.

Este enfoque maximiza el reutilización del código y ayuda a agregar elementos a áreas de contenido compartidas, como la navegación por secciones.

Aquí tienes algunas pautas para trabajar con la herencia:

  • Si utilizas {% extends %} en una plantilla, debe ser el primer tag de plantilla en esa plantilla. La herencia de plantillas no funcionará de otra manera.

  • Más etiquetas {% block %} en tus plantillas base son mejores. Recuerda que las plantillas hijas no necesitan definir todos los bloques de las plantillas padres, por lo que puedes llenar con valores razonables en varios bloques y luego solo definir los que necesites más adelante. Es mejor tener más puntos de conexión que pocos.

  • Si te encuentras duplicando contenido en varias plantillas, probablemente debes mover ese contenido a un {% block %} en una plantilla padre.

  • Si necesitas obtener el contenido del bloque de la plantilla padre, la variable {{ block.super }} hará el trabajo. Esto es útil si deseas agregar contenido al bloque de una plantilla padre en lugar de sobrescribirlo completamente. El contenido insertado con {{ block.super }} no se escapará automáticamente (ver la siguiente sección), ya que fue escapado, si era necesario, en la plantilla padre.

  • By using the same template name as you are inheriting from, {% extends %} se puede utilizar para heredar una plantilla al mismo tiempo que la sobreescribir. Combinado con {{ block.super }}, esto puede ser una forma poderosa de hacer pequeñas personalizaciones. Consulte Extender una plantilla sobrescrita en el Cómo hacerlo sobre Sobrescrituras de plantillas para un ejemplo completo.

  • Las variables creadas fuera de un {% block %} utilizando la sintaxis del marcador de plantilla as no pueden usarse dentro del bloque. Por ejemplo, esta plantilla no renderiza nada:

    {% translate "Title" as title %}
    {% block content %}{{ title }}{% endblock %}
    
  • Para una mayor legibilidad, puedes dar opcionalmente un nombre a tu etiqueta {% endblock %}. Por ejemplo:

    {% block content %}
    ...
    {% endblock content %}
    

    En plantillas más grandes, esta técnica te ayuda a ver qué etiquetas {% block %} están siendo cerradas.

  • Las etiquetas {% block %} se evalúan primero. Eso es por qué el contenido de un bloque siempre se sobreescribe, independientemente de la verdad de las etiquetas circundantes. Por ejemplo, esta plantilla siempre sobrescribirá el contenido del bloque title:

    {% if change_title %}
        {% block title %}Hello!{% endblock title %}
    {% endif %}
    

Finalmente, ten en cuenta que no puedes definir múltiples block etiquetas con el mismo nombre en la misma plantilla. Esta limitación existe porque una etiqueta de bloque funciona en «ambas» direcciones. Es decir, una etiqueta de bloque no solo proporciona un agujero para llenar – también define el contenido que llena el agujero en el padre. Si hubiera dos etiquetas block con el mismo nombre en una plantilla, ese padre no sabría qué uno de los bloques” contenido usar.

Escape HTML automático

Cuando se genera HTML desde plantillas, siempre existe un riesgo de que una variable incluya caracteres que afecten al resultado del HTML resultante. Por ejemplo, considera este fragmento de plantilla:

Hello, {{ name }}

Al principio, esto parece ser una forma inocua de mostrar el nombre de un usuario, pero considere qué pasaría si el usuario ingresó su nombre como este:

<script>alert('hello')</script>

Con este valor de nombre, la plantilla se renderizaría como:

Hello, <script>alert('hello')</script>

Los textos traducidos son:

De manera similar, ¿qué pasaría si el nombre contenía un símbolo '<' como este?

<b>username

Eso daría lugar a un template renderizado como este:

Hello, <b>username

…lo que, a su vez, haría que el resto de la página web estuviera en negrita!

Claramente, los datos suministrados por el usuario no deben confiarse ciegamente y ser insertados directamente en las páginas web, porque un usuario malintencionado podría utilizar este tipo de agujero para hacer cosas potencialmente dañinas. Este tipo de explotación de seguridad se conoce como ataque Cross Site Scripting (XSS).

Para evitar este problema, tienes dos opciones:

  • Una, puedes asegurarte de pasar cada variable no confiable a través del escape filtro (documentado más abajo), que convierte los caracteres HTML potencialmente dañinos en otros inofensivos. Esta fue la solución por defecto en Django durante sus primeros años, pero el problema es que pone la carga sobre , el desarrollador / autor del template, para asegurarte de escapar todo. Es fácil olvidarse de escapar los datos.

  • Dos, puedes aprovechar las funcionalidades de escape automático de Django. La parte restante de esta sección describe cómo funciona el escape automático.

Por defecto en Django, cada template escapa automáticamente la salida de cada etiqueta variable. Específicamente, estos cinco caracteres están escapados:

  • < se convierte en &lt;.

  • >` es convertido a ``&gt;

  • “ (comilla simple) se convierte en &#x27;

  • La comilla doble (») se convierte en &quot;

  • La traducción es:

Nuevamente, enfatizamos que este comportamiento está activado por defecto. Si estás utilizando el sistema de plantillas de Django, estás protegido.

Cómo desactivarlo

Si no deseas que los datos se escapen automáticamente, a nivel de sitio, plantilla o variable, puedes desactivarlo de varias maneras.

¿Por qué querrías desactivarlo? Porque a veces las variables de plantilla contienen datos que quieres que se rendericen como HTML no escapado. Por ejemplo, podrías almacenar un trozo de HTML en tu base de datos y querer insertarlo directamente en tu plantilla. O podrías estar utilizando el sistema de plantillas de Django para producir texto que no sea HTML – como un mensaje de correo electrónico, por ejemplo.

Para variables individuales

Para desactivar la escapada automática para una variable individual, utiliza el filtro safe:

This will be escaped: {{ data }}
This will not be escaped: {{ data|safe }}

Piensa en seguro como abreviatura de seguro desde la escapada adicional o puede ser interpretado con seguridad como HTML. En este ejemplo, si data contiene '<b>', la salida será:

This will be escaped: &lt;b&gt;
This will not be escaped: <b>

Para bloques de plantilla

Para controlar la escapada automática para una plantilla, envuelve la plantilla (o una sección particular de ella) en el etiqueta autoescape, como se muestra a continuación:

{% autoescape off %}
    Hello {{ name }}
{% endautoescape %}

La etiqueta autoescape acepta on o off como su argumento. En ocasiones, podrías querer forzar la escapada automática cuando de lo contrario estaría desactivada. Aquí tienes un ejemplo de plantilla:

Auto-escaping is on by default. Hello {{ name }}

{% autoescape off %}
    This will not be auto-escaped: {{ data }}.

    Nor this: {{ other_data }}
    {% autoescape on %}
        Auto-escaping applies again: {{ name }}
    {% endautoescape %}
{% endautoescape %}

La etiqueta de escapada automática transfiere su efecto a las plantillas que extiendan la actual así como a las incluidas mediante la etiqueta include, exactamente igual que todas las etiquetas de bloque. Por ejemplo:

base.html
{% autoescape off %}
<h1>{% block title %}{% endblock %}</h1>
{% block content %}
{% endblock %}
{% endautoescape %}
child.html
{% extends "base.html" %}
{% block title %}This &amp; that{% endblock %}
{% block content %}{{ greeting }}{% endblock %}

Porque la auto-escapada está desactivada en el plantilla base, también estará desactivada en la plantilla hija, lo que resulta en el siguiente HTML renderizado cuando la variable greeting contiene la cadena <b>Hello!</b>:

<h1>This &amp; that</h1>
<b>Hello!</b>

Notas

En general, los autores de las plantillas no necesitan preocuparse mucho por la auto-escapada. Los desarrolladores del lado Python (las personas que escriben vistas y filtros personalizados) deben pensar en los casos en los que los datos no deberían escaparse, y marcar los datos adecuadamente, para que todo funcione correctamente en la plantilla.

Si estás creando una plantilla que podría usarse en situaciones en las que no estés seguro si la auto-escapada está habilitada, entonces agrega un filtro escape a cualquier variable que necesite escaparse. Cuando la auto-escapada está activa, no hay peligro de doble-escapar los datos con el filtro escape – el filtro escape no afecta las variables auto-escapadas.

Cadenas literales y escapada automática

Como mencionamos anteriormente, los argumentos de los filtros pueden ser cadenas:

{{ data|default:"This is a string literal." }}

Todas las cadenas literales se insertan sin ninguna escapada automática en la plantilla – actúan como si fueran todas pasadas a través del filtro safe. La razón detrás de esto es que el autor de la plantilla tiene control sobre lo que se introduce en la cadena literal, por lo que pueden asegurarse de que el texto esté correctamente escapado cuando la plantilla está escrita.

Por tanto escribirías:

{{ data|default:"3 &lt; 2" }}

…en lugar de:

{{ data|default:"3 < 2" }}  {# Bad! Don't do this. #}

No afecta lo que sucede con los datos provenientes de la variable misma. Los contenidos de la variable siguen siendo escapados automáticamente, si es necesario, porque están más allá del control del autor del template.

Acceso a llamadas de método

La mayoría de las llamadas de método asociadas a objetos también están disponibles desde dentro de los templates. Esto significa que los templates tienen acceso a mucho más que solo a atributos de clase (como nombres de campo) y variables pasadas desde vistas. Por ejemplo, el ORM de Django proporciona la sintaxis «entry_set» para encontrar una colección de objetos relacionados en una clave foránea. Por lo tanto, dado un modelo llamado «comment» con una relación de clave foránea a un modelo llamado «task», puedes recorrer todos los comentarios asociados a una tarea determinada de la siguiente manera:

{% for comment in task.comment_set.all %}
    {{ comment }}
{% endfor %}

De manera similar, QuerySets proporcionan un método count() para contar el número de objetos que contienen. Por lo tanto, puedes obtener un recuento de todos los comentarios relacionados con la tarea actual con:

{{ task.comment_set.all.count }}

También puedes acceder a métodos que hayas definido explícitamente en tus propios modelos:

models.py
class Task(models.Model):
    def foo(self):
        return "bar"
template.html
{{ task.foo }}

Django limita intencionalmente la cantidad de lógica de procesamiento disponible en el lenguaje del template, por lo que no es posible pasar argumentos a llamadas de método accedidas desde dentro de los templates. Los datos deben calcularse en vistas y luego pasarse a los templates para su visualización.

Bibliotecas personalizadas de etiquetas y filtros

Ciertas aplicaciones proporcionan bibliotecas personalizadas de etiquetas y filtros. Para accederlas en un template, asegúrate de que la aplicación esté en INSTALLED_APPS (agregaríamos 'django.contrib.humanize' para este ejemplo), y luego utiliza el tag load en un template:

{% load humanize %}

{{ 45000|intcomma }}

En el ejemplo anterior, la etiqueta load carga la biblioteca de etiquetas humanize, que a su vez hace disponible el filtro intcomma para su uso. Si has habilitado django.contrib.admindocs, puedes consultar el área de documentación en tu administrador para encontrar la lista de bibliotecas personalizadas en tu instalación.

La etiqueta load puede tomar múltiples nombres de biblioteca, separados por espacios. Ejemplo:

{% load humanize i18n %}

Consulte Cómo crear etiquetas y filtros de plantilla personalizados para obtener información sobre la escritura de tus propias bibliotecas de etiquetas personalizadas.

Bibliotecas y herencia de plantillas

Cuando cargues una biblioteca de etiquetas o filtros personalizados, las etiquetas/filtros solo estarán disponibles para la plantilla actual – no para ninguna plantilla padre ni hija a lo largo del camino de herencia de plantillas.

Por ejemplo, si una plantilla foo.html tiene {% load humanize %}, una plantilla hija (por ejemplo, una que tenga {% extends "foo.html" %}) no tendrá acceso a las etiquetas y filtros de la biblioteca humanize. La plantilla hija es responsable de su propio {% load humanize %}.

Esto es un feature para el mantenimiento y la cordura.

Ver también

La Referencia de Plantillas

Cubre etiquetas incorporadas, filtros incorporados, uso de un lenguaje de plantilla alternativo y más.