PlantillasLink to this heading

Al ser un framework web, Django necesita una forma conveniente de generar HTML dinámicamente. El enfoque más común se basa en plantillas. Una plantilla contiene las partes estáticas de la salida HTML deseada, así como alguna sintaxis especial que describe cómo se insertará el contenido dinámico. Para ver un ejemplo práctico de cómo crear páginas HTML con plantillas, vea :doc:`Tutorial 3`</intro/tutorial03>.

Un proyecto Django se puede configurar con uno o varios motores de plantillas (o incluso ninguno si no usa plantillas). Django incluye backends integrados para su propio sistema de plantillas, creativamente denominado lenguaje de plantillas de Django (DTL), y para la popular alternativa Jinja2. Los backends para otros lenguajes de plantillas pueden estar disponibles através de terceros. También puede escribir su propio backend personalizado, consulte Custom template backend

Django define una API estándar para cargar y renderizar plantillas independientemente del backend. La carga consiste en encontrar la plantilla para un identificador determinado y preprocesarla, generalmente compilándola en una representación en memoria. Representar significa interpolar la plantilla con datos de contexto y devolver el texto resultante.

Django template language es el propio sistema de plantillas de Django. Hasta Django 1.8 era la única opción integrada disponible. Es una buena biblioteca de plantillas a pesar de que es bastante obstinada y tiene algunas idiosincrasias. Si no tiene una razón apremiante para elegir otro backend, debe usar DTL, especialmente si está escribiendo una aplicación conectable y tiene la intención de distribuir plantillas. Las aplicaciones de contribución de Django que incluyen plantillas, como django.contrib.admin, que también usa el DTL.

Por razones históricas, tanto el soporte genérico para motores de plantillas como la implementación del lenguaje de plantillas Django viven en el espacio de nombres django.template.

Lenguaje de plantillas de DjangoLink to this heading

SintaxisLink to this heading

Una plantilla de Django es un documento de texto o un texto de Python marcado con el lenguaje de plantillas de Django. Algunas construcciones son reconocidas e interpretadas por el motor de plantillas. Los principales son las variables y las etiquetas.

Una plantilla se representa con un contexto. La representación reemplaza las variables con sus valores, que se buscan en el contexto, y ejecuta las etiquetas. Todo lo demás se muestra tal cual.

La sintaxis del lenguaje de plantilla Django implica cuatro construcciones.

VariablesLink to this heading

Una variable genera un valor del contexto, que es un objeto similar a un diccionario que asigna llaves a valores.

Variables are surrounded by {{ and }} like this:

Django template
My first name is {{ first_name }}. My last name is {{ last_name }}.

With a context of {'first_name': 'John', 'last_name': 'Doe'}, this template renders to:

Django template
My first name is John. My last name is Doe.

Dictionary lookup, attribute lookup and list-index lookups are implemented with a dot notation:

Django template
{{ my_dict.key }}
{{ my_object.attribute }}
{{ my_list.0 }}

Si una variable se resuelve como invocable, el sistema de plantillas la llamará sin argumentos y usará su resultado en lugar del invocable.

EtiquetasLink to this heading

Las etiquetas proporcionan una lógica arbitraria en el proceso de representación.

Esta definición es deliberadamente vaga. Por ejemplo, una etiqueta puede generar contenido, servir como estructura de control. Por ejemplo: Una declaración «if» o un bucle «for», o obtener contenido de una base de datos o incluso habilitar el acceso a otras etiquetas de plantilla.

Tags are surrounded by {% and %} like this:

Django template
{% csrf_token %}

Most tags accept arguments:

Django template
{% cycle 'odd' 'even' %}

Some tags require beginning and ending tags:

Django template
{% if user.is_authenticated %}Hello, {{ user.username }}.{% endif %}

Puede consultar la referencia de etiquetas integradas así como las instrucciones para escribir etiquetas personalizadas.

FiltrosLink to this heading

Los filtros transforman los valores de las variables y los argumentos de las etiquetas.

They look like this:

Django template
{{ django|title }}

With a context of {'django': 'the web framework for perfectionists with deadlines'}, this template renders to:

Django template
The Web Framework For Perfectionists With Deadlines

Some filters take an argument:

Django template
{{ my_date|date:"Y-m-d" }}

Puede consultar la referencia de filtros integrados así como las instrucciones para escribir filtros personalizados.

ComentariosLink to this heading

Comments look like this:

Django template
{# this won't be rendered #}

Una etiqueta {% comment %} proporciona comentarios de varias líneas.

ComponentesLink to this heading

MotorLink to this heading

django.template.Engine encapsula una instancia del sistema de plantillas de Django. La razón principal para instanciar una Engine directamente es usar el lenguaje de plantillas Django fuera de un proyecto Django.

django.template.backends.django.DjangoTemplates es un contenedor sencillo que adapta django.template.Engine a la API backend de plantilla de Django.

PlantillaLink to this heading

django.template.Template representa una plantilla compilada. Las plantillas se obtienen con Engine.get_template() o Engine.from_string().

Del mismo modo, django.template.backends.django.Template es un contenedor sencillo que adapta django.template.Template a la API de plantilla común.

ContextoLink to this heading

django.template.Context contiene algunos metadatos además de los datos de contexto. Se pasa a Template.render() para renderizar una plantilla.

django.template.RequestContext es una subclase de Context que almacena la HttpRequest actual y ejecuta procesadores de contexto de plantilla.

La API común no tiene un concepto equivalente. Los datos de contexto se pasan en un simple dict y el HttpRequest actual se pasa por separado si es necesario.

CargadoresLink to this heading

Los cargadores de plantillas son responsables de ubicar plantillas, cargarlas y devolver objetos Template.

Django proporciona varios cargadores de plantillas integrados y admite cargadores de plantillas personalizados.

Procesadores de contextoLink to this heading

Los procesadores de contexto son funciones que reciben la HttpRequest actual como argumento y devuelven un dict de datos para agregar al contexto de la renderización.

Su uso principal es agregar datos comunes compartidos por todas las plantillas al contexto sin repetir el código en cada vista.

Django proporciona muchos procesadores de contexto integrados, y también puede implementar sus propios procesadores de contexto adicionales.

Soporte para motores de plantillasLink to this heading

ConfiguraciónLink to this heading

Los motores de plantillas están configurados con la configuración TEMPLATES. Es una lista de configuraciones, una para cada motor. El valor predeterminado está vacío. El settings.py generado por el comando startproject define un valor más útil:

Code
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [],
        "APP_DIRS": True,
        "OPTIONS": {
            # ... some options here ...
        },
    },
]

BACKEND es una ruta punteada de Python a una clase de motor de plantilla que implementa la API backend de plantilla de Django. Los backends integrados son django.template.backends.django.DjangoTemplates y django.template.backends.jinja2.Jinja2.

Dado que la mayoría de los motores cargan plantillas desde archivos, la configuración de nivel superior para cada motor contiene dos configuraciones comunes:

  • DIRS define una lista de directorios donde el motor debe buscar archivos fuente de plantilla, en orden de búsqueda.

  • APP_DIRS indica si el motor debe buscar plantillas dentro de las aplicaciones instaladas. Cada backend define un nombre convencional para el subdirectorio dentro de las aplicaciones donde se deben almacenar sus plantillas.

Si bien es poco común, es posible configurar varias instancias del mismo backend con diferentes opciones. En ese caso, debe definir un NAME para cada motor.

:settings:`OPTIONS <TEMPLATES-OPTIONS>` contiene configuraciones específicas de back-end.

UsageLink to this heading

El módulo django.template.loader define dos funciones para cargar plantillas.

get_template(template_name, using=None)Link to this definition

Esta función carga la plantilla con el nombre dado y devuelve un objeto Template.

El tipo exacto del valor devuelto depende del backend que cargó la plantilla. Cada backend tiene su propia clase Template.

get_template() prueba cada motor de plantilla en orden hasta que uno tenga éxito. Si no se puede encontrar la plantilla, genera TemplateDoesNotExist. Si se encuentra la plantilla pero contiene una sintaxis no válida, genera un TemplateSyntaxError.

La forma en que se buscan y cargan las plantillas depende del backend y la configuración de cada motor.

Si desea restringir la búsqueda a un motor de plantilla en particular, pase el NAME del motor en el argumento using.

select_template(template_name_list, using=None)Link to this definition

select_template() es como get_template(), excepto que toma una lista de nombres de plantillas. Prueba cada nombre en orden y devuelve la primera plantilla que existe.

Si falla la carga de una plantilla, se pueden generar las siguientes dos excepciones, definidas en django.template:

exception TemplateDoesNotExist(msg, tried=None, backend=None, chain=None)Link to this definition

Esta excepción se genera cuando no se puede encontrar una plantilla. Acepta los siguientes argumentos opcionales para completar la template postmortem en la página de depuración:

backend

La instancia de back-end de la plantilla desde la que se originó la excepción.

tried

Una lista de las fuentes que se probaron al encontrar la plantilla. Esto tiene el formato de una lista de tuplas que contienen (origen, estado), donde origen es un objeto `similar al origen` y estado es una cadena con el motivo por el cual la plantilla no fue encontrada.

chain

Una lista de excepciones intermedias TemplateDoesNotExist generadas al intentar cargar una plantilla. Esto lo utilizan funciones, como get_template(), que intentan cargar una plantilla determinada desde varios motores.

exception TemplateSyntaxError(msg)Link to this definition

Esta excepción se genera cuando se encuentra una plantilla pero contiene errores.

Los objetos Template devueltos por get_template() y select_template() deben proporcionar un método render() con la siguiente firma:

Template.render(context=None, request=None)Link to this definition

Representa esta plantilla con un contexto dado.

Si se proporciona context, debe ser un dict. Si no se proporciona, el motor representará la plantilla con un contexto vacío.

Si se proporciona request, debe ser una HttpRequest. Luego, el motor debe hacerlo, así como el token CSRF, disponible en la plantilla. Cómo se logra esto depende de cada backend.

Aquí hay un ejemplo del algoritmo de búsqueda. Para este ejemplo, la configuración TEMPLATES es:

Code
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [
            "/home/html/example.com",
            "/home/html/default",
        ],
    },
    {
        "BACKEND": "django.template.backends.jinja2.Jinja2",
        "DIRS": [
            "/home/html/jinja2",
        ],
    },
]

Si llama a get_template('story_detail.html'), aquí están los archivos que buscará Django, en orden:

  • /home/html/example.com/story_detail.html (motor ``”django””)

  • /home/html/default/story_detail.html (motor 'django')

  • /home/html/jinja2/story_detail.html (motor 'jinja2')

Si llama a select_template(['story_253_detail.html', 'story_detail.html']), esto es lo que buscará Django:

  • /home/html/example.com/story_253_detail.html (motor 'django')

  • /home/html/default/story_253_detail.html (motor 'django')

  • /home/html/jinja2/story_253_detail.html (motor 'jinja2')

  • /home/html/example.com/story_detail.html (motor ``”django””)

  • /home/html/default/story_detail.html (motor 'django')

  • /home/html/jinja2/story_detail.html (motor 'jinja2')

Cuando Django encuentra una plantilla que existe, deja de buscar.

Es posible, y preferible, organizar las plantillas en subdirectorios dentro de cada directorio que contiene plantillas. La convención es crear un subdirectorio para cada aplicación de Django, con subdirectorios dentro de esos subdirectorios según sea necesario.

Haga esto por su propia tranquilidad. Almacenar todas las plantillas en el nivel raíz de un solo directorio se puede complicar.

Para cargar una plantilla que está dentro de un subdirectorio, use una barra diagonal, así:

Code
get_template("news/story_detail.html")

Usando la misma opción TEMPLATES que la anterior, esto intentará cargar las siguientes plantillas:

  • /home/html/example.com/news/story_detail.html (motor 'django')

  • /home/html/default/news/story_detail.html (motor 'django')

  • /home/html/jinja2/news/story_detail.html (motor 'jinja2')

Además, para reducir la naturaleza repetitiva de cargar y renderizar plantillas, Django proporciona una función de acceso directo que automatiza el proceso.

render_to_string(template_name, context=None, request=None, using=None)Link to this definition

render_to_string() carga una plantilla como get_template() y llama a su método render() inmediatamente. Toma los siguientes argumentos.

template_name

El nombre de la plantilla para cargar y renderizar. Si es una lista de nombres de plantillas, Django usa select_template() en lugar de get_template() para encontrar la plantilla.

context

Un dict que se utilizará como contexto de la plantilla para la representación.

request

Una HttpRequest opcional que estará disponible durante el proceso de renderización de la plantilla.

using

Un motor de plantillas opcional NAME. La búsqueda de la plantilla estará restringida a ese motor.

Ejemplo de uso:

Code
from django.template.loader import render_to_string

rendered = render_to_string("my_template.html", {"foo": "bar"})

Consulte también el acceso directo render() que llama a render_to_string() y envía el resultado a una HttpResponse adecuada para retornarlo desde una vista.

Finalmente, puede usar los motores configurados directamente:

enginesLink to this definition

Los motores de plantillas están disponibles en django.template.engines:

Code
from django.template import engines

django_engine = engines["django"]
template = django_engine.from_string("Hello {{ name }}!")

La clave de búsqueda, — 'django' en este ejemplo, es el NAME del motor.

Backends incorporadosLink to this heading

class DjangoTemplatesLink to this definition

Establezca el BACKEND en 'django.template.backends.django.DjangoTemplates' para configurar un motor de plantillas de Django.

Cuando APP_DIRS es True, los motores DjangoTemplates buscan plantillas en el subdirectorio templates de las aplicaciones instaladas. Este nombre genérico se mantuvo por compatibilidad con versiones anteriores.

Los motores DjangoTemplates aceptan las siguientes OPTIONS:

  • 'autoescape': un valor booleano que controla si el escape automático de HTML está habilitado.

    Por defecto es True.

  • 'context_processors': una lista de rutas punteadas de Python a invocables que se usan para llenar el contexto cuando una plantilla se procesa con una solicitud. Estos invocables toman un objeto de solicitud como argumento y devuelven un dict de elementos que se fusionarán en el contexto.

    Por defecto es una lista vacía.

    Consulte RequestContext para obtener más información.

  • 'debug': un valor booleano que activa/desactiva el modo de depuración de plantillas. Si es True, la elegante página de error mostrará un informe detallado de cualquier excepción que surja durante la representación de la plantilla. Este informe contiene el fragmento relevante de la plantilla con la línea correspondiente resaltada.

    El valor predeterminado es el de la configuración DEBUG.

  • 'loaders': una lista de rutas punteadas de Python a clases de cargadores de plantillas. Cada clase Loader sabe cómo importar plantillas desde una fuente en particular. Opcionalmente, se puede usar una tupla en lugar de una cadena. El primer elemento de la tupla debe ser el nombre de la clase Loader, y los elementos subsiguientes se pasan al Loader durante la inicialización.

    El valor predeterminado depende de los valores de DIRS y APP_DIRS.

    Ver Loader types para más información.

  • 'string_if_invalid': la salida, como una cadena de caractéres, que el sistema de plantilla debe usar para variables no válidas (p. ej., mal escritas).

    Por defecto es una cadena de caractéres vacía.

    Ver How invalid variables are handled para más información.

  • 'file_charset': el conjunto de caracteres utilizado para leer archivos de plantilla en el disco.

    Por defecto es 'utf-8''.

  • 'bibliotecas': un diccionario de etiquetas y rutas de Python punteadas de módulos de etiquetas de plantillas para registrarse con el motor de plantillas. Esto se puede usar para agregar nuevas bibliotecas o proporcionar etiquetas alternativas para las existentes. Por ejemplo:

    Code
    OPTIONS = {
        "libraries": {
            "myapp_tags": "path.to.myapp.tags",
            "admin.urls": "django.contrib.admin.templatetags.admin_urls",
        },
    }
    

    Las bibliotecas se pueden cargar pasando la clave del diccionario correspondiente a la etiqueta {% load %}.

  • 'builtins': una lista de rutas de Python punteadas de módulos de etiquetas de plantilla para agregar a built-ins. Por ejemplo:

    Code
    OPTIONS = {
        "builtins": ["myapp.builtins"],
    }
    

    Las etiquetas y los filtros de las bibliotecas integradas se pueden usar sin llamar primero a la etiqueta {% load %}.

class Jinja2Link to this definition

Requiere que Jinja2 esté instalado:

Linux / macOS

Shell
$ python -m pip install Jinja2

Windows

Windows
...\> py -m pip install Jinja2

Establezca BACKEND en 'django.template.backends.jinja2.Jinja2'' para configurar un motor Jinja2.

Cuando APP_DIRS ` es ``True`, los motores Jinja2 buscan plantillas en el subdirectorio jinja2 de las aplicaciones instaladas.

La entrada más importante en OPTIONS es 'environment'. Es una ruta de Python punteada a un invocable que retorna un entorno Jinja2. Por defecto es 'jinja2.Environment'. Django invoca ese invocable y pasa otras opciones como argumentos de palabras clave. Además, Django agrega valores predeterminados que difieren de los de Jinja2 para algunas opciones:

  • 'autoescape': True

  • 'loader': un cargador configurado para DIRS y APP_DIRS

  • 'auto_reload': settings.DEBUG

  • 'undefined': DebugUndefined if settings.DEBUG else Undefined

Los motores Jinja2 también aceptan la siguiente OPTIONS:

  • 'context_processors': una lista de rutas punteadas de Python a invocables que se usan para llenar el contexto cuando una plantilla se procesa con una solicitud. Estos invocables toman un objeto de solicitud como argumento y devuelven un dict de elementos que se fusionarán en el contexto.

    Por defecto es una lista vacía.

La configuración predeterminada se mantiene deliberadamente al mínimo. Si una plantilla se procesa con una solicitud (por ejemplo, cuando se usa render()), el backend Jinja2 agrega los globales request, csrf_input y csrf_token al contexto. Aparte de eso, este backend no crea un entorno con sabor a Django. No conoce los filtros y etiquetas de Django. Para usar las API específicas de Django, debe configurarlas en el entorno.

Por ejemplo, puede crear myproject/jinja2.py con este contenido:

Code
from django.templatetags.static import static
from django.urls import reverse

from jinja2 import Environment


def environment(**options):
    env = Environment(**options)
    env.globals.update(
        {
            "static": static,
            "url": reverse,
        }
    )
    return env

y establezca la opción 'environment' en 'myproject.jinja2.environment'.

Entonces podría usar las siguientes construcciones en las plantillas de Jinja2:

Html Jinja
<img src="{{ static('path/to/company-logo.png') }}" alt="Company Logo">

<a href="{{ url('admin:index') }}">Administration</a>

Los conceptos de etiquetas y filtros existen tanto en el lenguaje de plantillas de Django como en Jinja2, pero se usan de manera diferente. Dado que Jinja2 admite pasar argumentos a invocables en plantillas, muchas funciones que requieren una etiqueta de plantilla o un filtro en las plantillas de Django se pueden lograr llamando a una función en las plantillas de Jinja2, como se muestra en el ejemplo anterior. El espacio de nombres global de Jinja2 elimina la necesidad de procesadores de contexto de plantilla. El lenguaje de plantillas Django no tiene un equivalente de las pruebas de Jinja2.