miércoles, 21 de diciembre de 2022

4.- Django - Cargadores de Plantillas.

Hasta ahora para cargar una plantilla creábamos una variable y usábamos el método "open", le especificamos la ruta de la plantilla. Después utilizábamos el objeto "Template" para pasarle por parámetro el objeto que acabamos de cargar y lo leíamos con el metodo "read".  Y más tarde le decíamos que renderizará ese objeto Template utilizando un contexto


views.py

...
# Vistas

def saludo(request):
    doc_externo = open(
        "/home/chema/Cursos/DJANGO/Proyecto1/plantillas/plantilla.html")
    plantilla = Template(doc_externo.read())
    doc_externo.close()

    nombre = "Antonio"
    fecha_actual = datetime.datetime.now()

    ciudades = ["Barcelona", "Madrid", "León", "Caceres"]

    # Al contexto hay que pasarle un diccionario que se usara para transferir a el valor
    # a la plantilla
    contexto = Context(
        {"nombre_usuario": nombre, "date": fecha_actual, "lugares": ciudades})
    documento = plantilla.render(contexto)
    return HttpResponse(documento)
...


Hay una forma más eficiente de hacer todo esto que es utilizando un cargador o "loader". Consiste en decirle al proyecto de Django que las plantillas se encuentran en un directorio en concreto, al que normalmente se denomina templates (aunque puedes llamarlo como quieras, aquí seguiremos llamándole plantillas). Después cuando vayamos a utilizar una plantilla, todo lo anterior se va a hacer automáticamente, ahorrando recursos y varias líneas de código.

Primeramente debemos decirle a Django donde está la carpeta que contiene nuestras plantillas. Esto se hace en el archivo settings.py y buscamos una variable llamada TEMPLATES. Es una lista que contiene un diccionario una de cuyas claves es DIRS que por defecto aparece vacío.

Nota: Si utilizas como nombre del directorio "templates", que es el que se utiliza por defecto, y no un nombre personalizado como "plantillas" que he usado yo, no tendrás que registrar el directorio de las plantillas en settings.py


TEMPLATES dentro de settings.py


Es aquí donde pondremos la ruta del directorio que contiene nuestras plantillas. En mi caso se llama "plantillas" pero puedes usar el nombre que quieras. Lo modificamos para que incluya la ruta de las plantillas, en mi caso:


settings.py

...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': ["/home/chema/Cursos/DJANGO/Proyecto1/plantillas"],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]


Una vez hecho esto, importamos el cargador o "loader" en views.py:

from django.template.loader import get_template

views.py

from django.http import HttpResponse
import datetime
# Al utilizar un cargador la siguiente línea no hace falta.
# from django.template import Template, Context
from django.template.loader import get_template

# Vistas

def saludo(request):
    doc_externo = open(
        "/home/chema/Cursos/DJANGO/Proyecto1/plantillas/plantilla.html")
    plantilla = Template(doc_externo.read())
...

Después de importar el loader borramos (yo lo voy a comentar para ver la diferencia) la línea que cargaba el programa, creaba el objeto "Template" y cerraba el documento.

views.py

def saludo(request):
    # Al utilizar un cargador esto no hace falta ya.
    # doc_externo = open("/home/chema/Cursos/DJANGO/Proyecto1/plantillas/plantilla.html")
    # plantilla = Template(doc_externo.read())
    # doc_externo.close()

    nombre = "Antonio"
    fecha_actual = datetime.datetime.now()

    ciudades = ["Barcelona", "Madrid", "León", "Caceres"]

    doc_externo = get_template("plantilla.html")

    contexto = {"nombre_usuario": nombre, "date": fecha_actual, "lugares": ciudades}
    documento = doc_externo.render(contexto)
    return HttpResponse(documento)

Y todo va a quedar más sencillo. 

Creamos una variable (doc_externo) que cargará la plantilla o plantilla que queramos usando "get_template".

 Date cuenta que ya no hay que especificar la ruta de la plantilla. Ya no necesitamos tampoco ni el objeto Template ni el objeto context. Ahora sencillamente al doc_externo que ha cargado la plantilla lo renderizamos con el método render al que tenemos que pasar un diccionario y no un objeto "context" como hacíamos antes.


Y LO MAS PRACTICO VIENE AHORA ->

Incluso podemos abreviar más el código si utilizamos atajos o "shortcut functions" que Django nos facilita. Aquí nos viene una función muy útil, llamada "render()" que hará que podamos prescindir de casi todo y nos quedará todo el proceso de carga y renderizado en una única línea. Para ello primero tenemos que importar en views.py lo siguiente:

from django.shorcuts import render 

y veréis en lo que se nos queda el código.

views.py (archivo final para cargar una plantilla externa usando el menor código)

from django.http import HttpResponse
import datetime

from django.shortcuts import render

# Vistas

def saludo(request):
    nombre = "Antonio"
    fecha_actual = datetime.datetime.now()

    ciudades = ["Barcelona", "Madrid", "León", "Caceres"]
    
    contexto = {"nombre_usuario": nombre, "date": fecha_actual, "lugares": ciudades}
    
    return render(request, "plantilla.html", contexto)


En vez de retornar un objeto HttpResponse como hicimos hasta ahora, retornamos un objeto render en el que ya especificamos como primer argumento el "request", como segundo el nombre de la plantilla entre comillas y como tercero podemos pasarle el contexto como una variable o pasarle directamente el diccionario. Así de fácil y con una sola línea de código podemos renderizar una plantilla con un determinado contexto.

No hay comentarios:

Publicar un comentario