Como se ha comentado anteriormente, las plantillas tienen una serie de variables y etiquetas de bloques que son necesario resolver y evaluar para determinar la plantilla final que será mostrada en el navegador del cliente. Para realizar dichas operaciones se utilizan los contextos en las plantillas. Un contexto por lo tanto será una equivalencia entre las distintas variables y su valor correspondiente, que se corresponderá con un diccionario en Python. Se representan mediante la clase Context del módulo django.template. Es en las vistas donde se asignará un contexto a una plantilla para cuando se haga el render de la plantilla, se sustituya cada variable por su valor.
- 71 -
11.8.1 Procesadores de contexto
Aparte de que el contexto sea una instancia de django.template.Context, también puede ser de django.template.RequestContext, lo cual cambiará ligeramente la funcionalidad. Esta clase aporta diferentes variables al contexto tales como un objeto HttpRequest y algunos datos del usuario de la aplicación en ese momento, entre otras posibilidades. Mediante el uso de RequestContext junto con los procesadores de contexto, el programador podrá evitar numerosas líneas de código repetidas ya que permitirán incluir un determinado número de variables en diferentes plantillas sin tener que volverlas a declarar en cada una. Un procesador de contexto será una función Python que tomará como argumento un objeto HttpRequest y retorna el diccionario con las variables que se van a incluir automáticamente en el contexto para cada plantilla que lo ejecute, según la opción de configuración del procesador de contextos del motor. Dicha opción será una lista de procesadores de contextos, que se encuentra en settings.py, el archivo de configuración que se crea por defecto con el proyecto Django. Vienen los siguientes procesadores de contexto cuando se crea una aplicación nueva con el motor de plantillas por defecto DjangoTemplates:
• 'django.template.context_processors.debug'
• 'django.template.context_processors.request,
• 'django.contrib.auth.context_processors.auth'
• ‘django.contrib.messages.context_processors.messages'
Django viene con algunos procesadores de contextos incluidos con un determinado número de variables cada uno de ellos. Se pasa a crear una tabla para nombrar cada uno:
Procesador de Contexto Variables
django.contrib.auth.context_processors.auth user, perms
django.template.context_processors.debug debug, sql_queries django.template.context_processors.i18n LANGUAGES,
LANGUAGE_CODE django.template.context_processors.media MEDIA_URL
django.template.context_processors.static STATIC_URL
django.template.context_processors.csrf Facilita un token para la etiqueta csrf_token. django.template.context_processors.request request django.template.context_processors.tz TIME_ZONE django.contrib.messages.context_processors.messa ges messages, DEFAULT_MESSAGE_LEVE LS
Tabla 13 - Tabla de procesadores de contexto de Django.
Si se usan estos procesadores de contexto de Django, cada RequestContext tendrá las variables propias de cada uno de ellos
Django permite escribir procesadores de contextos personalizados con el objetivo de poder incluir otras variables no contempladas en los casos anteriores.
- 72 -
Por lo tanto, una vista, a la hora de definir el procesador a utilizar, deberá de indicar que se trata de RequestContext, al que pasará los siguientes argumentos:
- Un objeto HttpRequest en primer lugar.
- Un diccionario Python por si se desea integrar alguna variable adicional.
- Como parámetro opcional, recibirá una lista de funciones de procesadores de contexto adicionales que usará. Se guarda en la variable processors.
11.8.2 Renderizado de plantillas
Con el contexto creado y la plantilla correctamente implementada, es necesario relacionar una plantilla con un contexto para que se produzca la traducción de variables y obtener la plantilla final. Esto se realiza mediante el proceso de renderizado de plantillas. Por lo tanto, una vez que se tiene una instancia de la clase Template, que será la plantilla y un determinado contexto, es necesario llamar a la función Template.render() de la plantilla, pasándole como argumento el contexto dado. Con todo ello, quedaría la plantilla formada correctamente habiéndose traducido las variables y evaluado las etiquetas de los bloques. Django a modo de atajo aporta el método render() del módulo django.shortcuts el cual permite realizar lo anteriormente comentado en una sola línea de código, lo que ayuda a reducir código al programador. Dicho atajo que aporta Django permite realizar en una sola llamada:
- La carga de la plantilla, es decir, evita tener que llamar a loader.get_template().
- La generación de un contexto para esa plantilla.
- Por último, evita tener que realizar el proceso de renderización de la plantilla por separado.
Por lo que los argumentos que recibirá dicha función serán: la plantilla a utilizar en primer lugar y un diccionario de forma opcional de segundo argumento. El contexto creado por este atajo por defecto será un RequestContext. Por último, cabe comentar que devuelve un HttpResponse, por lo que se puede retornar en la función vista.
A continuación se pasa a mostrar el código para comprobar el código que permite ahorrarse el método render():
- 73 -
• Código sin atajo.
• Código con atajo render().
Otro atajo que ofrece Django es django.shortcuts.render_to_response(). Éste es el antecesor del anterior, render(). Funciona de la misma manera salvo que la solicitud, el objeto request, no está disponible en la respuesta. Por esta casuística que se acaba de comentar, la función render_to_response() tenderá a desaparecer en futuras versiones de Django.
Es necesario llevar a cabo este proceso de renderización de plantillas, debido ya que una de ellas por sí sola no puede asignar o modificar el valor de una variable, para ello se han creado los contextos.
Django permite que una misma plantilla se pueda utilizar con múltiples contextos llevando a cabo el renderizado con cada uno de ellos. Esta ventaja que aporta Django sirve para evitar tener una duplicidad de código, lo que concuerda con su principio básico DRY.
from django.template.loader import get_template
from django.template import Context
from django.http import HttpResponse
def cliente(request):
no_usuario = request.user
id_usuario = get_object_or_404(Cliente, user = no_usuario)
lista_entradas_futuras = Entrada.objects.filter(id_cliente =
id_usuario).filter(fechaHora__gte=datetime.datetime.now()).order_by(
'id_entrada')
lista_comentarios = Comentario.objects.filter(usuario =
id_usuario).order_by('pelicula')
template_cliente = get_template('usuario.html')
html_res =
template_cliente.render(Context({'usuario':id_usuario,
'entradas_f':lista_entradas_futuras,
'comentarios':lista_comentarios}))
return HttpResponse(html_res)
from django.shortcuts import render, get_object_or_404
def cliente(request):
no_usuario = request.user
id_usuario = get_object_or_404(Cliente, user = no_usuario)
lista_entradas_futuras = Entrada.objects.filter(id_cliente =
id_usuario).filter(fechaHora__gte=datetime.datetime.now()).order_by(
'id_entrada')
lista_comentarios = Comentario.objects.filter(usuario =
id_usuario).order_by('pelicula')
return render(request, 'usuario.html', {'usuario':id_usuario,
'entradas_f':lista_entradas_futuras,
'entradas_p':lista_entradas_pasadas,