Este documento explica el sistema de plantillas de Django desde una perspectiva técnica: cómo funciona y cómo extenderlo. Si está buscando una referencia sobre la sintaxis del lenguaje, consulte El lenguaje de la plantilla de Django.
Supone una comprensión de las plantillas, los contextos, las variables, las etiquetas y la representación. Empiece con el introducción al lenguaje de plantillas de Django si no está familiarizado con estos conceptos.
Visión general
El uso del sistema de plantillas en Python es un proceso de tres pasos:
- Configuras un
Engine
. - Compila el código de la plantilla en un
Template
. - Usted renderiza la plantilla con un
Context
.
Los proyectos de Django generalmente se basan en API de alto nivel, agnósticas de backend para cada uno de estos pasos en lugar de las API de nivel inferior del sistema de plantillas:
- Para cada
DjangoTemplates
backend en elTEMPLATES
, Django crea una instanciaEngine
.DjangoTemplates
envuelveEngine
y lo adapta a la API de backend de plantilla común. - los
django.template.loader
módulo proporciona funciones tales comoget_template()
para cargar plantillas. Devuelven undjango.template.backends.django.Template
que envuelve el realdjango.template.Template
. - los
Template
obtenido en el paso anterior tiene unrender()
método que ordena un contexto y posiblemente una solicitud en unContext
y delega la interpretación al subyacenteTemplate
.
Configurar un motor
Si está utilizando el DjangoTemplates
backend, probablemente esta no sea la documentación que está buscando. Una instancia del Engine
la clase descrita a continuación es accesible usando el engine
El atributo de ese backend y los valores predeterminados de los atributos que se mencionan a continuación se anulan por lo que se pasa por DjangoTemplates
.
-
class Engine(dirs=None, app_dirs=False, context_processors=None, debug=False, loaders=None, string_if_invalid='', file_charset="utf-8", libraries=None, builtins=None, autoescape=True)
-
Al crear una instancia
Engine
todos los argumentos deben pasarse como argumentos de palabra clave:-
dirs
es una lista de directorios donde el motor debe buscar archivos fuente de plantilla. Se utiliza para configurarfilesystem.Loader
.Por defecto es una lista vacía.
-
app_dirs
solo afecta al valor predeterminado deloaders
. Vea abajo.Por defecto es
False
. -
autoescape
controla si el escape automático de HTML está habilitado.Por defecto es
True
.Advertencia
Solo configúrelo en
False
si está renderizando plantillas que no son HTML! -
context_processors
es una lista de rutas de Python con puntos a los que se pueden llamar que se utilizan para completar el contexto cuando se procesa una plantilla con una solicitud. Estos invocables toman un objeto de solicitud como argumento y devuelven undict
de elementos que se fusionarán en el contexto.Por defecto es una lista vacía.
Ver
RequestContext
para más información. -
debug
es un booleano que activa / desactiva el modo de depuración de plantilla. Si esto esTrue
, el motor de plantillas almacenará información de depuración adicional que se puede utilizar para mostrar un informe detallado de cualquier excepción que se produzca durante la representación de la plantilla.Por defecto es
False
. -
loaders
es una lista de clases de cargadores de plantillas, especificadas como cadenas. CadaLoader
la clase sabe cómo importar plantillas de una fuente en particular. Opcionalmente, se puede utilizar una tupla en lugar de una cadena. El primer elemento de la tupla debe ser elLoader
nombre de la clase, los elementos subsiguientes se pasan alLoader
durante la inicialización.Tiene como valor predeterminado una lista que contiene:
'django.template.loaders.filesystem.Loader'
-
'django.template.loaders.app_directories.Loader'
si y solo siapp_dirs
esTrue
.
Si
debug
esFalse
, estos cargadores están envueltos endjango.template.loaders.cached.Loader
.Ver Tipos de cargadores para detalles.
-
string_if_invalid
es la salida, como una cadena, que el sistema de plantillas debe usar para las variables inválidas (por ejemplo, mal escritas).Por defecto es la cadena vacía.
Ver Cómo se manejan las variables inválidas para detalles.
-
file_charset
es el juego de caracteres utilizado para leer archivos de plantilla en el disco.Por defecto es
'utf-8'
. -
'libraries'
: Un diccionario de etiquetas y rutas de Python con puntos de módulos de etiquetas de plantilla para registrar con el motor de plantillas. Esto se usa para agregar nuevas bibliotecas o proporcionar etiquetas alternativas para las existentes. Por ejemplo:Engine( 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 al
{% load %}
etiqueta. -
"https://foroayuda.es/django/ref/templates/builtins"
: Una lista de rutas de Python con puntos de módulos de etiquetas de plantilla para agregar incorporados. Por ejemplo:Engine( builtins=['myapp.builtins'], )
Las etiquetas y filtros de las bibliotecas integradas se pueden usar sin llamar primero al
{% load %}
etiqueta.
-
-
static Engine.get_default()
-
Devuelve el subyacente
Engine
desde el primer configuradoDjangoTemplates
motor. ElevaImproperlyConfigured
si no hay motores configurados.Es necesario para preservar las API que dependen de un motor configurado implícitamente disponible globalmente. Se desaconseja encarecidamente cualquier otro uso.
-
Engine.from_string(template_code)
-
Compila el código de plantilla dado y devuelve un
Template
objeto.
-
Engine.get_template(template_name)
-
Carga una plantilla con el nombre de pila, la compila y devuelve un
Template
objeto.
-
Engine.select_template(template_name_list)
-
Igual que
get_template()
, excepto que toma una lista de nombres y devuelve la primera plantilla que se encontró.
Cargando una plantilla
La forma recomendada de crear un Template
es llamando a los métodos de fábrica del Engine
: get_template()
, select_template()
y from_string()
.
En un proyecto de Django donde el TEMPLATES
el ajuste define un DjangoTemplates
motor, es posible crear una instancia Template
directamente. Si mas de uno DjangoTemplates
motor está definido, se utilizará el primero.
-
class Template
-
Esta clase vive en
django.template.Template
. El constructor toma un argumento: el código de plantilla sin formato:from django.template import Template template = Template("My name is {{ my_name }}.")
Entre bastidores
El sistema solo analiza el código de la plantilla sin procesar una vez, cuando crea el Template
objeto. A partir de ese momento, se almacena internamente como una estructura de árbol para el rendimiento.
Incluso el análisis en sí es bastante rápido. La mayor parte del análisis se realiza mediante una única llamada a una única expresión regular corta.
Representar un contexto
Una vez que haya compilado Template
objeto, puede representar un contexto con él. Puede reutilizar la misma plantilla para renderizarla varias veces con diferentes contextos.
-
class Context(dict_=None)
-
El constructor de
django.template.Context
toma un argumento opcional: un diccionario que asigna nombres de variables a valores de variables.Para obtener más detalles, consulte Jugando con objetos de contexto debajo.
-
Template.render(context)
-
Llama a
Template
objetosrender()
método con unContext
para “llenar” la plantilla:>>> from django.template import Context, Template >>> template = Template("My name is {{ my_name }}.") >>> context = Context({"my_name": "Adrian"}) >>> template.render(context) "My name is Adrian." >>> context = Context({"my_name": "Dolores"}) >>> template.render(context) "My name is Dolores."
Variables y búsquedas
Los nombres de las variables deben constar de cualquier letra (AZ), cualquier dígito (0-9), un guión bajo (pero no deben comenzar con un guión bajo) o un punto.
Los puntos tienen un significado especial en la representación de plantillas. Un punto en el nombre de una variable significa buscar. Específicamente, cuando el sistema de plantillas encuentra un punto en el nombre de una variable, intenta las siguientes búsquedas, en este orden:
- Búsqueda de diccionario. Ejemplo:
foo["bar"]
- Búsqueda de atributos. Ejemplo:
foo.bar
- Búsqueda de índice de lista. Ejemplo:
foo[bar]
Tenga en cuenta que “barra” en una expresión de plantilla como {{ foo.bar }}
se interpretará como una cadena literal y sin utilizar el valor de la variable “bar”, si existe alguna en el contexto de la plantilla.
El sistema de plantillas utiliza el primer tipo de búsqueda que funciona. Es lógica de cortocircuito. Aquí están algunos ejemplos:
>>> from django.template import Context, Template >>> t = Template("My name is {{ person.first_name }}.") >>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}} >>> t.render(Context(d)) "My name is Joe." >>> class PersonClass: pass >>> p = PersonClass() >>> p.first_name = "Ron" >>> p.last_name = "Nasty" >>> t.render(Context({"person": p})) "My name is Ron." >>> t = Template("The first stooge in the list is {{ stooges.0 }}.") >>> c = Context({"stooges": ["Larry", "Curly", "Moe"]}) >>> t.render(c) "The first stooge in the list is Larry."
Si alguna parte de la variable es invocable, el sistema de plantillas intentará llamarla. Ejemplo:
>>> class PersonClass2: ... def name(self): ... return "Samantha" >>> t = Template("My name is {{ person.name }}.") >>> t.render(Context({"person": PersonClass2})) "My name is Samantha."
Las variables invocables son un poco más complejas que las variables que solo requieren búsquedas directas. A continuación, se incluyen algunas cosas a tener en cuenta:
-
Si la variable genera una excepción cuando se llama, la excepción se propagará, a menos que la excepción tenga un atributo
silent_variable_failure
cuyo valor esTrue
. Si la excepcion lo hace tener unsilent_variable_failure
atributo cuyo valor esTrue
, la variable se representará como el valor del motorstring_if_invalid
opción de configuración (una cadena vacía, por defecto). Ejemplo:>>> t = Template("My name is {{ person.first_name }}.") >>> class PersonClass3: ... def first_name(self): ... raise AssertionError("foo") >>> p = PersonClass3() >>> t.render(Context({"person": p})) Traceback (most recent call last): ... AssertionError: foo >>> class SilentAssertionError(Exception): ... silent_variable_failure = True >>> class PersonClass4: ... def first_name(self): ... raise SilentAssertionError >>> p = PersonClass4() >>> t.render(Context({"person": p})) "My name is ."
Tenga en cuenta que
django.core.exceptions.ObjectDoesNotExist
, que es la clase base para todas las API de base de datos de DjangoDoesNotExist
excepciones, tienesilent_variable_failure = True
. Entonces, si está usando plantillas de Django con objetos de modelo de Django, cualquierDoesNotExist
la excepción fallará silenciosamente. - Solo se puede llamar a una variable si no tiene argumentos requeridos. De lo contrario, el sistema devolverá el valor del motor
string_if_invalid
opción.
-
Puede haber efectos secundarios al llamar a algunas variables, y sería una tontería o un agujero de seguridad permitir que el sistema de plantillas acceda a ellas.
Un buen ejemplo es el
delete()
en cada objeto de modelo de Django. No se debe permitir que el sistema de plantillas haga algo como esto:I will now delete this valuable data. {{ data.delete }}
Para evitar esto, establezca un
alters_data
atributo en la variable invocable. El sistema de plantillas no llamará a una variable si tienealters_data=True
set, y en su lugar reemplazará la variable constring_if_invalid
, incondicionalmente. El generado dinámicamentedelete()
ysave()
los métodos en los objetos del modelo de Django obtienenalters_data=True
automáticamente. Ejemplo:def sensitive_function(self): self.database_record.delete() sensitive_function.alters_data = True
- Ocasionalmente, es posible que desee desactivar esta función por otras razones y decirle al sistema de plantillas que deje una variable sin llamar sin importar qué. Para hacerlo, establezca un
do_not_call_in_templates
atributo en el invocable con el valorTrue
. El sistema de plantilla actuará como si su variable no fuera invocable (permitiéndole acceder a los atributos de la invocable, por ejemplo).
Cómo se manejan las variables inválidas
Generalmente, si una variable no existe, el sistema de plantillas inserta el valor del motor string_if_invalid
opción de configuración, que se establece en ''
(la cadena vacía) de forma predeterminada.
Los filtros que se aplican a una variable no válida solo se aplicarán si string_if_invalid
se establece en ''
(la cadena vacía). Si string_if_invalid
se establece en cualquier otro valor, los filtros de variables se ignorarán.
Este comportamiento es ligeramente diferente para el if
, for
y regroup
etiquetas de plantilla. Si se proporciona una variable no válida a una de estas etiquetas de plantilla, la variable se interpretará como None
. Los filtros siempre se aplican a las variables no válidas dentro de estas etiquetas de plantilla.
Si string_if_invalid
contiene una '%s'
, el marcador de formato se reemplazará con el nombre de la variable no válida.
¡Solo con fines de depuración!
Tiempo string_if_invalid
puede ser una herramienta de depuración útil, es una mala idea activarla como un “valor predeterminado de desarrollo”.
Muchas plantillas, incluidas algunas de Django, dependen del silencio del sistema de plantillas cuando se encuentra una variable inexistente. Si asigna un valor que no sea ''
para string_if_invalid
, experimentará problemas de representación con estas plantillas y sitios.
Generalmente, string_if_invalid
solo debe habilitarse para depurar un problema de plantilla específico, luego borrarse una vez que se completa la depuración.
Variables integradas
Cada contexto contiene True
, False
y None
. Como era de esperar, estas variables se resuelven en los correspondientes objetos de Python.
Limitaciones con cadenas literales
El lenguaje de plantilla de Django no tiene forma de escapar de los caracteres utilizados para su propia sintaxis. Por ejemplo, el templatetag
La etiqueta es necesaria si necesita generar secuencias de caracteres como {%
y %}
.
Existe un problema similar si desea incluir estas secuencias en filtros de plantilla o argumentos de etiquetas. Por ejemplo, al analizar una etiqueta de bloque, el analizador de plantillas de Django busca la primera aparición de %}
después de {%
. Esto evita el uso de "%}"
como una cadena literal. Por ejemplo, un TemplateSyntaxError
se generará para las siguientes expresiones:
{% include "template.html" tvar="Some string literal with %} in it." %} {% with tvar="Some string literal with %} in it." %}{% endwith %}
El mismo problema se puede desencadenar mediante el uso de una secuencia reservada en los argumentos de filtro:
{{ some.variable|default:"}}" }}
Si necesita utilizar cadenas con estas secuencias, guárdelas en variables de plantilla o utilice una etiqueta de plantilla personalizada o un filtro para solucionar la limitación.
Jugando con Context
objetos
La mayoría de las veces, creará una instancia Context
objetos pasando en un diccionario completamente poblado a Context()
. Pero puede agregar y eliminar elementos de un Context
objeto una vez que se ha creado una instancia, también, utilizando la sintaxis de diccionario estándar:
>>> from django.template import Context >>> c = Context({"foo": "bar"}) >>> c['foo'] 'bar' >>> del c['foo'] >>> c['foo'] Traceback (most recent call last): ... KeyError: 'foo' >>> c['newvariable'] = 'hello' >>> c['newvariable'] 'hello'
-
Context.get(key, otherwise=None)
-
Devuelve el valor de
key
sikey
está en el contexto, de lo contrario regresaotherwise
.
-
Context.setdefault(key, default=None)
-
Si
key
está en el contexto, devuelve su valor. De lo contrario insertakey
con un valor dedefault
y vuelvedefault
.
-
Context.pop()
-
Context.push()
-
exception ContextPopException
A Context
el objeto es una pila. Es decir, puedes push()
y pop()
eso. Si tu pop()
demasiado, subirá django.template.ContextPopException
:
>>> c = Context() >>> c['foo'] = 'first level' >>> c.push() {} >>> c['foo'] = 'second level' >>> c['foo'] 'second level' >>> c.pop() {'foo': 'second level'} >>> c['foo'] 'first level' >>> c['foo'] = 'overwritten' >>> c['foo'] 'overwritten' >>> c.pop() Traceback (most recent call last): ... ContextPopException
También puedes usar push()
como administrador de contexto para asegurar una coincidencia pop()
se llama.
>>> c = Context() >>> c['foo'] = 'first level' >>> with c.push(): ... c['foo'] = 'second level' ... c['foo'] 'second level' >>> c['foo'] 'first level'
Todos los argumentos pasados a push()
será pasado a la dict
constructor utilizado para construir el nuevo nivel de contexto.
>>> c = Context() >>> c['foo'] = 'first level' >>> with c.push(foo='second level'): ... c['foo'] 'second level' >>> c['foo'] 'first level'
-
Context.update(other_dict)
Además de push()
y pop()
, los Context
El objeto también define un update()
método. Esto funciona como push()
pero toma un diccionario como argumento y empuja ese diccionario a la pila en lugar de uno vacío.
>>> c = Context() >>> c['foo'] = 'first level' >>> c.update({'foo': 'updated'}) {'foo': 'updated'} >>> c['foo'] 'updated' >>> c.pop() {'foo': 'updated'} >>> c['foo'] 'first level'
Igual que push()
, puedes usar update()
como administrador de contexto para asegurar una coincidencia pop()
se llama.
>>> c = Context() >>> c['foo'] = 'first level' >>> with c.update({'foo': 'second level'}): ... c['foo'] 'second level' >>> c['foo'] 'first level'
Usando un Context
como una pila es útil en algunas etiquetas de plantilla personalizadas.
-
Context.flatten()
Utilizando flatten()
método que puedes conseguir completo Context
apilar como un diccionario que incluye variables integradas.
>>> c = Context() >>> c['foo'] = 'first level' >>> c.update({'bar': 'second level'}) {'bar': 'second level'} >>> c.flatten() {'True': True, 'None': None, 'foo': 'first level', 'False': False, 'bar': 'second level'}
A flatten()
El método también se utiliza internamente para hacer Context
objetos comparables.
>>> c1 = Context() >>> c1['foo'] = 'first level' >>> c1['bar'] = 'second level' >>> c2 = Context() >>> c2.update({'bar': 'second level', 'foo': 'first level'}) {'foo': 'first level', 'bar': 'second level'} >>> c1 == c2 True
El resultado de flatten()
puede ser útil en pruebas unitarias para comparar Context
contra dict
:
class ContextTest(unittest.TestCase): def test_against_dictionary(self): c1 = Context() c1['update'] = 'value' self.assertEqual(c1.flatten(), { 'True': True, 'None': None, 'False': False, 'update': 'value', })
Utilizando RequestContext
-
class RequestContext(request, dict_=None, processors=None)
Django viene con un especial Context
clase, django.template.RequestContext
, que actúa de forma ligeramente diferente a la normal django.template.Context
. La primera diferencia es que se necesita un HttpRequest
como su primer argumento. Por ejemplo:
c = RequestContext(request, { 'foo': 'bar', })
La segunda diferencia es que llena automáticamente el contexto con algunas variables, de acuerdo con el motor context_processors
opción de configuración.
los context_processors
La opción es una lista de personas que se pueden llamar, llamada procesadores de contexto – que toman un objeto de solicitud como argumento y devuelven un diccionario de elementos para fusionarlos en el contexto. En el archivo de configuración generado por defecto, el motor de plantilla predeterminado contiene los siguientes procesadores de contexto:
[ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ]
Además de estos, RequestContext
siempre habilita 'django.template.context_processors.csrf'
. Este es un procesador de contexto relacionado con la seguridad requerido por el administrador y otras aplicaciones contrib y, en caso de una mala configuración accidental, está deliberadamente codificado y no se puede apagar en el context_processors
opción.
Cada procesador se aplica en orden. Eso significa que si un procesador agrega una variable al contexto y un segundo procesador agrega una variable con el mismo nombre, el segundo anulará al primero. Los procesadores predeterminados se explican a continuación.
Cuando se aplican procesadores de contexto
Los procesadores de contexto se aplican sobre los datos de contexto. Esto significa que un procesador de contexto puede sobrescribir las variables que ha proporcionado a su Context
o RequestContext
, así que tenga cuidado de evitar nombres de variables que se superpongan con los proporcionados por sus procesadores de contexto.
Si desea que los datos de contexto tengan prioridad sobre los procesadores de contexto, utilice el siguiente patrón:
from django.template import RequestContext request_context = RequestContext(request) request_context.push({"my_name": "Adrian"})
Django hace esto para permitir que los datos de contexto anulen los procesadores de contexto en API como render()
y TemplateResponse
.
Además, puedes dar RequestContext
una lista de procesadores adicionales, utilizando el tercer argumento posicional opcional, processors
. En este ejemplo, el RequestContext
instancia obtiene una ip_address
variable:
from django.http import HttpResponse from django.template import RequestContext, Template def ip_address_processor(request): return {'ip_address': request.META['REMOTE_ADDR']} def client_ip_view(request): template = Template('{{ title }}: {{ ip_address }}') context = RequestContext(request, { 'title': 'Your IP Address', }, [ip_address_processor]) return HttpResponse(template.render(context))
Procesadores de contexto de plantilla integrados
Esto es lo que hace cada uno de los procesadores integrados:
django.contrib.auth.context_processors.auth
-
auth()
Si este procesador está habilitado, cada RequestContext
contendrá estas variables:
-
user
– Unauth.User
instancia que representa al usuario actualmente conectado (o unAnonymousUser
ejemplo, si el cliente no ha iniciado sesión). -
perms
– Una instancia dedjango.contrib.auth.context_processors.PermWrapper
, que representa los permisos que tiene el usuario actualmente conectado.
django.template.context_processors.debug
-
debug()
Si este procesador está habilitado, cada RequestContext
contendrá estas dos variables, pero solo si su DEBUG
la configuración está establecida en True
y la dirección IP de la solicitud (request.META['REMOTE_ADDR']
) está en el INTERNAL_IPS
configuración:
-
debug
–True
. Puede usar esto en plantillas para probar si está enDEBUG
modo. -
sql_queries
– Una lista de{'sql': ..., 'time': ...}
diccionarios, que representan cada consulta SQL que ha ocurrido hasta ahora durante la solicitud y cuánto tiempo ha tardado. La lista está ordenada por alias de la base de datos y luego por consulta. Se genera perezosamente en el acceso.
django.template.context_processors.i18n
-
i18n()
Si este procesador está habilitado, cada RequestContext
contendrá estas variables:
-
LANGUAGES
– El valor de laLANGUAGES
configuración. -
LANGUAGE_BIDI
–True
si el idioma actual es un idioma de derecha a izquierda, por ejemplo, hebreo, árabe.False
si es un idioma de izquierda a derecha, por ejemplo, inglés, francés, alemán. -
LANGUAGE_CODE
–request.LANGUAGE_CODE
, si existiera. De lo contrario, el valor de laLANGUAGE_CODE
configuración.
Ver Etiquetas de plantilla i18n para etiquetas de plantilla que generan los mismos valores.
django.template.context_processors.media
Si este procesador está habilitado, cada RequestContext
contendrá una variable MEDIA_URL
, proporcionando el valor de la MEDIA_URL
configuración.
django.template.context_processors.static
-
static()
Si este procesador está habilitado, cada RequestContext
contendrá una variable STATIC_URL
, proporcionando el valor de la STATIC_URL
configuración.
django.template.context_processors.csrf
Este procesador agrega un token que necesita el csrf_token
etiqueta de plantilla para protección contra Falsificaciones de solicitudes entre sitios.
django.template.context_processors.request
Si este procesador está habilitado, cada RequestContext
contendrá una variable request
, que es la actual HttpRequest
.
django.template.context_processors.tz
-
tz()
Si este procesador está habilitado, cada RequestContext
contendrá una variable TIME_ZONE
, proporcionando el nombre de la zona horaria actualmente activa.
django.contrib.messages.context_processors.messages
Si este procesador está habilitado, cada RequestContext
contendrá estas dos variables:
-
messages
– Una lista de mensajes (como cadenas) que se han configurado a través del marco de mensajes. -
DEFAULT_MESSAGE_LEVELS
– Un mapeo de los nombres de nivel de mensaje a su valor numérico.
Escribir sus propios procesadores de contexto
Un procesador de contexto tiene una interfaz simple: es una función de Python que toma un argumento, un HttpRequest
objeto y devuelve un diccionario que se agrega al contexto de la plantilla.
Por ejemplo, para agregar el DEFAULT_FROM_EMAIL
ajuste a cada contexto:
from django.conf import settings def from_email(request): return { "DEFAULT_FROM_EMAIL": settings.DEFAULT_FROM_EMAIL, }
Los procesadores de contexto personalizados pueden vivir en cualquier lugar de su base de código. Todo lo que le importa a Django es que sus procesadores de contexto personalizados estén apuntados por el 'context_processors'
opción en tu TEMPLATES
ajuste – o el context_processors
argumento de Engine
si lo está usando directamente.
Cargando plantillas
Generalmente, almacenará las plantillas en archivos en su sistema de archivos en lugar de usar el nivel bajo Template
API usted mismo. Guarde las plantillas en un directorio especificado como directorio de plantillas.
Django busca directorios de plantillas en varios lugares, dependiendo de la configuración de carga de su plantilla (consulte “Tipos de cargadores” a continuación), pero la forma más básica de especificar directorios de plantillas es mediante el uso de DIRS
opción.
los DIRS
opción
Dígale a Django cuáles son sus directorios de plantillas usando el DIRS
opción en el TEMPLATES
en su archivo de configuración – o el dirs
argumento de Engine
. Esto debe establecerse en una lista de cadenas que contengan rutas completas a los directorios de su plantilla:
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [ '/home/html/templates/lawrence.com', '/home/html/templates/default', ], }, ]
Sus plantillas pueden ir a cualquier lugar que desee, siempre que el servidor web pueda leer los directorios y las plantillas. Pueden tener cualquier extensión que desee, como .html
o .txt
o no pueden tener ninguna extensión.
Tenga en cuenta que estas rutas deben usar barras diagonales de estilo Unix, incluso en Windows.
Tipos de cargadores
De forma predeterminada, Django usa un cargador de plantillas basado en el sistema de archivos, pero Django viene con algunos otros cargadores de plantillas, que saben cómo cargar plantillas de otras fuentes.
Algunos de estos otros cargadores están deshabilitados de forma predeterminada, pero puede activarlos agregando un 'loaders'
opción a tu DjangoTemplates
backend en el TEMPLATES
establecer o pasar un loaders
argumento para Engine
. loaders
debe ser una lista de cadenas o tuplas, donde cada una representa una clase de cargador de plantillas. Aquí están los cargadores de plantillas que vienen con Django:
django.template.loaders.filesystem.Loader
-
class filesystem.Loader
-
Carga plantillas del sistema de archivos, de acuerdo con
DIRS
.Este cargador está habilitado de forma predeterminada. Sin embargo, no encontrará ninguna plantilla hasta que establezca
DIRS
a una lista no vacía:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], }]
También puede anular
'DIRS'
y especificar directorios específicos para un cargador de sistema de archivos en particular:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ( 'django.template.loaders.filesystem.Loader', [BASE_DIR / 'templates'], ), ], }, }]
django.template.loaders.app_directories.Loader
-
class app_directories.Loader
-
Carga plantillas de aplicaciones Django en el sistema de archivos. Para cada aplicación en
INSTALLED_APPS
, el cargador busca untemplates
subdirectorio. Si el directorio existe, Django busca plantillas allí.Esto significa que puede almacenar plantillas con sus aplicaciones individuales. Esto también ayuda a distribuir aplicaciones de Django con plantillas predeterminadas.
Por ejemplo, para esta configuración:
INSTALLED_APPS = ['myproject.polls', 'myproject.music']
…luego
get_template('foo.html')
buscaráfoo.html
en estos directorios, en este orden:/path/to/myproject/polls/templates/
/path/to/myproject/music/templates/
… Y usará el que encuentre primero.
El orden de
INSTALLED_APPS
¡es significante! Por ejemplo, si desea personalizar el administrador de Django, puede optar por anular el estándaradmin/base_site.html
plantilla, dedjango.contrib.admin
, contigo mismoadmin/base_site.html
enmyproject.polls
. A continuación, debe asegurarse de que sumyproject.polls
proviene antes dedjango.contrib.admin
enINSTALLED_APPS
, de lo contrariodjango.contrib.admin
Las de primero se cargarán y las suyas se ignorarán.Tenga en cuenta que el cargador realiza una optimización cuando se ejecuta por primera vez: almacena en caché una lista de los
INSTALLED_APPS
los paquetes tienen untemplates
subdirectorio.Puede habilitar este cargador configurando
APP_DIRS
paraTrue
:TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'APP_DIRS': True, }]
django.template.loaders.cached.Loader
-
class cached.Loader
-
Por defecto (cuando
DEBUG
esTrue
), el sistema de plantillas lee y compila sus plantillas cada vez que se procesan. Si bien el sistema de plantillas de Django es bastante rápido, la sobrecarga de leer y compilar plantillas puede sumarse.Configura el cargador de plantillas en caché con una lista de otros cargadores que debe envolver. Los cargadores envueltos se utilizan para localizar plantillas desconocidas cuando se encuentran por primera vez. El cargador en caché luego almacena el compilado
Template
en memoria. El cachéTemplate
La instancia se devuelve para solicitudes posteriores para cargar la misma plantilla.Este cargador se habilita automáticamente si
OPTIONS['loaders']
no está especificado yOPTIONS['debug']
esFalse
(la última opción tiene por defecto el valor deDEBUG
).También puede habilitar el almacenamiento en caché de plantillas con algunos cargadores de plantillas personalizados usando configuraciones como esta:
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [BASE_DIR / 'templates'], 'OPTIONS': { 'loaders': [ ('django.template.loaders.cached.Loader', [ 'django.template.loaders.filesystem.Loader', 'django.template.loaders.app_directories.Loader', 'path.to.custom.Loader', ]), ], }, }]
Nota
Todas las etiquetas de plantilla de Django integradas son seguras de usar con el cargador en caché, pero si está utilizando etiquetas de plantilla personalizadas que provienen de paquetes de terceros, o que usted mismo escribió, debe asegurarse de que el
Node
La implementación de cada etiqueta es segura para subprocesos. Para más información, ver Consideraciones de seguridad de subprocesos de etiquetas de plantilla.
django.template.loaders.locmem.Loader
-
class locmem.Loader
-
Carga plantillas de un diccionario de Python. Esto es útil para realizar pruebas.
Este cargador toma un diccionario de plantillas como primer argumento:
TEMPLATES = [{ 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'OPTIONS': { 'loaders': [ ('django.template.loaders.locmem.Loader', { 'index.html': 'content here', }), ], }, }]
Este cargador está desactivado de forma predeterminada.
Django usa los cargadores de plantillas en orden de acuerdo con 'loaders'
opción. Utiliza cada cargador hasta que un cargador encuentra una coincidencia.
Cargadores personalizados
Es posible cargar plantillas de fuentes adicionales utilizando cargadores de plantillas personalizados. Personalizado Loader
las clases deben heredar de django.template.loaders.base.Loader
y definir el get_contents()
y get_template_sources()
métodos.
Métodos de cargador
-
class Loader
-
Carga plantillas de una fuente determinada, como el sistema de archivos o una base de datos.
-
get_template_sources(template_name)
-
Un método que requiere
template_name
y rindeOrigin
instancias para cada fuente posible.Por ejemplo, el cargador del sistema de archivos puede recibir
'index.html'
como untemplate_name
argumento. Este método daría origen a la ruta completa deindex.html
como aparece en cada directorio de plantillas que mira el cargador.El método no necesita verificar que la plantilla exista en una ruta determinada, pero debe garantizar que la ruta sea válida. Por ejemplo, el cargador del sistema de archivos se asegura de que la ruta se encuentre en un directorio de plantilla válido.
-
get_contents(origin)
-
Devuelve el contenido de una plantilla dada una
Origin
ejemplo.Aquí es donde un cargador del sistema de archivos leería el contenido del sistema de archivos, o un cargador de la base de datos leería de la base de datos. Si no existe una plantilla coincidente, esto debería generar un
TemplateDoesNotExist
error.
-
get_template(template_name, skip=None)
-
Devuelve un
Template
objeto para un dadotemplate_name
recorriendo los resultados deget_template_sources()
y llamandoget_contents()
. Esto devuelve la primera plantilla coincidente. Si no se encuentra ninguna plantilla,TemplateDoesNotExist
es elevado.El opcional
skip
El argumento es una lista de orígenes que se deben ignorar al extender plantillas. Esto permite que las plantillas amplíen otras plantillas del mismo nombre. También se utiliza para evitar errores de recursividad.En general, basta con definir
get_template_sources()
yget_contents()
para cargadores de plantillas personalizadas.get_template()
normalmente no será necesario anularlo.
-
Construyendo tu propio
Por ejemplo, lea el código fuente para los cargadores integrados de Django.
Origen de la plantilla
Las plantillas tienen un origin
que contienen atributos según la fuente desde la que se cargan.
-
class Origin(name, template_name=None, loader=None)
-
-
name
-
La ruta a la plantilla devuelta por el cargador de plantillas. Para los cargadores que leen desde el sistema de archivos, esta es la ruta completa a la plantilla.
Si se crea una instancia de la plantilla directamente en lugar de a través de un cargador de plantillas, este es un valor de cadena de
<unknown_source>
.
-
template_name
-
La ruta relativa a la plantilla que se pasó al cargador de plantillas.
Si se crea una instancia de la plantilla directamente en lugar de a través de un cargador de plantillas, esto es
None
.
-
loader
-
La instancia del cargador de plantillas que construyó este
Origin
.Si se crea una instancia de la plantilla directamente en lugar de a través de un cargador de plantillas, esto es
None
.django.template.loaders.cached.Loader
requiere que todos sus cargadores envueltos establezcan este atributo, por lo general creando una instancia delOrigin
conloader=self
.
-