# documentación de Django - 5.2.8

# Plantillas

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`.

Advertencia

El sistema de plantillas no es seguro frente a autores de plantillas que no son de confianza. Por ejemplo, un sitio no debe permitir que sus usuarios proporcionen sus propias plantillas, ya que los autores de plantillas pueden hacer cosas como realizar ataques XSS y acceder a las propiedades de las variables de plantilla que pueden contener información confidencial.

## Lenguaje de plantillas de Django

### Sintaxis

Acerca de esta sección

Esta es una descripción general de la sintaxis del lenguaje de plantilla de Django. Para obtener más información, consulte la referencia de sintaxis del idioma.

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.

#### Variables

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

Las variables están rodeadas por `{{` y `}}` así:

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

Con un contexto de `{'first_name': 'John', 'last_name': 'Doe'}`, esta plantilla se renderiza como:

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

La búsqueda de diccionario, la búsqueda de atributos y las búsquedas de índice de lista se implementan con una notación de punto:

    {{ 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.

#### Etiquetas

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:

    {% csrf_token %}

Most tags accept arguments:

    {% cycle 'odd' 'even' %}

Some tags require beginning and ending tags:

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

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

#### Filtros

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

They look like this:

    {{ django|title }}

Con un contexto de `{'django': 'the web framework for perfectionists with deadlines'}`, esta plantilla se renderiza como:

    The Web Framework For Perfectionists With Deadlines

Some filters take an argument:

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

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

#### Comentarios

Comments look like this:

    {# this won't be rendered #}

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

### Componentes

Acerca de esta sección

Esta es una descripción general de la API del lenguaje de plantilla de Django. Para obtener más información, consulte la referencia de la API

#### Motor

`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.

#### Plantilla

`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.

#### Contexto

`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.

#### Cargadores

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 contexto

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 plantillas

### Configuración

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:

    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.

`OPTIONS` contiene configuraciones específicas de back-end.

### Uso

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

get_template(template_name, using=None)

  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`.

  Partial loading:

  When using the `DjangoTemplates` backend, a specific fragment from a template can be loaded by name. This fragment should have been previously defined using the `partialdef` template tag:

      from django.template.loader import get_template

      # Load an entire template.
      template = get_template("template.html")

      # Load a specific fragment from a template.
      partial = get_template("template.html#partial_name")

  When loading a partial, the returned object behaves like a regular `Template` but contains only the partial’s content.

  See Template partials for more information about defining and using template fragments.

  Changed in Django 6.0:

  Support for loading template partials when using the `DjangoTemplates` backend was added.

select_template(template_name_list, using=None)

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

  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)

  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)

  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:

    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.

Use `django.template.loader.select_template()` for more flexibility

You can use `select_template()` for flexible template loading. For example, if you’ve written a news story and want some stories to have custom templates, use something like `select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])`. That’ll allow you to use a custom template for an individual story, with a fallback template for stories that don’t have custom templates.

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í:

    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)

  `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:

      from django.template.loader import render_to_string

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

See also the `render()` shortcut which calls `render_to_string()` and feeds the result into an `HttpResponse` suitable for returning from a view.

Finalmente, puede usar los motores configurados directamente:

engines

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

      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 incorporados

class DjangoTemplates

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`.

  Advertencia

  ¡Ajústelo a `False` solo si está representando plantillas que no son HTML!

- `'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:

      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:

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

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

class Jinja2

Requiere que Jinja2 esté instalado:

/ 

    $ python -m pip install Jinja2

    ...\> 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.

  Se desaconseja el uso de procesadores de contexto con plantillas Jinja2.

  Los procesadores de contexto son útiles con las plantillas de Django porque las plantillas de Django no admiten funciones de llamada con argumentos. Dado que Jinja2 no tiene esa limitación, se recomienda colocar la función que usaría como procesador de contexto en las variables globales disponibles para la plantilla usando `jinja2.Environment` como se describe a continuación. A continuación, puede llamar a esa función en la plantilla:

      {{ function(request) }}

  Algunos procesadores de contexto de plantillas de Django devuelven un valor fijo. Para las plantillas de Jinja2, esta capa de direccionamiento indirecto no es necesaria ya que puede agregar constantes directamente en `jinja2.Environment`.

  El caso de uso original para agregar procesadores de contexto para Jinja2 involucraba:

  - Haciendo un alto consumo computacional que depende de la solicitud.

  - Necesitando el resultado en cada plantilla.

  - Usando el resultado varias veces en cada plantilla.

  A menos que se cumplan todas estas condiciones, pasar una función a la plantilla está más en línea con el diseño de Jinja2.

The default configuration is purposefully kept to a minimum. If a template is rendered with a request (e.g. when using `render()`), the `Jinja2` backend adds the globals `request`, `csrf_input`, and `csrf_token` to the context. Apart from that, this backend doesn’t create a Django-flavored environment. It doesn’t know about Django filters and tags. In order to use Django-specific APIs, you must configure them into the environment.

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

    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:

    <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.