miércoles, 7 de diciembre de 2022

2.- Django - Contenido dinámico e Introducción de Parámetros en URL.

En la primera página que mostramos en el post anterior, correspondiente al "Hola Mundo", se mostraba un contenido estático. Aunque cargaras la página web varias veces siempre se mostraba lo mismo. 

Vamos a diseñar ahora una página que nos muestre la hora y fecha del servidor, con lo que cada vez que actualices la página se mostrará una información diferente - Dinámico -. Además, podemos pasar esta información formateada, usando como parámetro del método HttpResponse con código HTML, en vez de un string.

Y ¿Cómo hacemos esto?

Pues partimos del ejemplo del capitulo anterior. En el archivo views.py,  creamos una vista más de la siguiente forma:

views.py

from django.http import HttpResponse
import datetime

# Vistas
...
# Nueva vista que mostrará la hora actual.
def fecha_actual(request):

    date = datetime.datetime.now()

    # Estructura de un documento tipo html5
    documento = f"""
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Fecha Servidor</title>
    </head>
    <body>
        <h2>
            Fecha y hora Actuales: {date}
        </h2>    
    </body>
    </html>
    """
    return HttpResponse(documento)
Para empezar importamos la biblioteca datatime ya que es la que utilizaremos para mostrar la fecha y hora actuales. 

Creamos la variable date que almacenará esa fecha y hora.

Creamos la nueva vista. La Función de esta vista la he llamado "fecha_actual". Para darle formato a la salida utilizamos la variable documento que recoge la estructura básica de un documento html5. Al final no es más que un string con lo que podemos introducir información, como lo haríamos normalmente en Python - f"texto {variable}" -

El siguiente paso es registrar esa vista en el archivo que guarda las urls, urls.py.

urls.py

from django.contrib import admin
from django.urls import path
from Proyecto1.views import saludo, fecha_actual

urlpatterns = [
    path('admin/', admin.site.urls),
    path('saludo/', saludo),
    path("time_server/", fecha_actual),
]
Importamos la función fecha_actual al principio. Luego para acceder a la vista hay que usar el nombre "time_server" que hace referencia a la vista o función "fecha_Actual". Como comentamos en el post anterior el nombre para acceder a la vista "time_server" no tiene que ser necesariamente el nombre de la función "fecha_actual" aunque es lo más recomendable.

Vamos a ver si funciona. Ejecutamos el servidor de pruebas con:

$ python manage.py runserver

Salida:

muestra fecha servidor en pantalla


Puedes ver como va cambiando refrescando el navegador con F5.


Paso de Parámetros a través de la URL.


Para ver como se hace, vamos a ver un ejemplo, en el que pasando dos números a través de una vista nos muestre su suma.

Como en los casos anteriores lo primero es crear la función de la vista.

IMPORTANTE: Por defecto los parámetros que se pasan a través de una URL son de tipo string. Por eso si necesitamos, como en este caso, que sean numéricos hay que ponerlos con este formato:

/<int: parámetro>

Comentar que aparte de <int:loquesea> también se pueden utilizar los siguientes comandos para modificar el tipo de parámetros que introducimos en la Url:

  • string: Acepta cualquier texto sin barras (por defecto). Si no ponemos nada en el parámetro como ya dijimos lo considera como un string, una cadena de texto.
  • int: para convertirlo en enteros
  • float: para  valores reales, con decimales.
  • path: Acepta cadena de caracteres con barras


Otra opción es sabiendo que al pasárselos a la función, estos datos que son de tipo string, los convirtamos luego dentro de la función al tipo de datos que necesitemos usando Python. (por ejemplo int(parametro) )

Dicho lo cual la forma general de pasar los parámetros es:

def nombre_vista(request, parametro1, parametro2,...,parametro_n):
        -----
        -----
        -----
        return HttpResponse(documento)


Creamos la función de la nueva vista.

views.py

# Suma dos números pasados como parámetros en la Url
def suma_numeros(request, numero_1, numero_2):
    documento = documento = f"""
    <!DOCTYPE html>
    <html lang="es">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Fecha Servidor</title>
    </head>
    <body>
        <h3>
            La suma de {numero_1} más {numero_2} = {numero_1 + numero_2}
            <hr/>
        </h3>    
    </body>
    </html>
    """
    return HttpResponse(documento)

Para registrar la URL la forma general es:

path("Nombre_Url/<parametro_1>/<parametro_2>/..../<parametro_n>/", nombre_vista)

en nuestro ejemplo, como necesitamos que los parámetros se pasen como enteros para sumarlos:

urls.py

from django.contrib import admin
from django.urls import path
from Proyecto1.views import saludo, fecha_actual, suma_numeros

urlpatterns = [
    path('admin/', admin.site.urls),
    path('saludo/', saludo),
    path("time_server/", fecha_actual),
    path("suma_numeros/<int:numero_1>/<int:numero_2>/", suma_numeros),
]

Como siempre, importamos la función y luego registramos la URL.

Salida:

paso de parametros a través de url
Plantillas - Son cadenas de texto que pueden tener código Html o ser texto plano simplemente. Sirven para separar la parte lógica de la parte visual del proyecto. Aunque hay muchas formas de utilizar las plantillas la más habitual es guardar todo el código HTML en un documento aparte y en otra carpeta distinta y luego la cargarla en nuestra vista.

Para crear una plantilla, básicamente seguimos tres pasos:

1.) Creación de un objeto tipo Template.
2.) Creación de un contexto (Contenido dinámico, variables, funciones etc)
3.) Renderizado del template.

Vamos a pasar todo esto a código con el proyecto que estamos usando desde el post inicial. En el proyecto que estamos usando ya teníamos una función en views.py llamada "saludo" que nos devolvía un texto plano. Vamos a hacer que nos devuelva el mismo texto pero usando una plantilla para que nos sirva de ejemplo.

Vamos a crear un nuevo archivo que será la plantilla que vamos a crear y la guardaremos también en una carpeta nueva, separada que por ejemplo podemos llamar "plantillas", aunque normalmente se suele llamar "templates".

directorio para plantillas


plantilla.html (guardada en directorio "plantillas")

<!DOCTYPE html>
<html lang="es">
<head>
     <meta charset="UTF-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Fecha Servidor</title>
</head>
<body>
      <h3>
         ¡Hola Mundo! He sido cargada desde una plantilla.
      </h3>    
</body>
</html>

Ahora volvemos a el archivo views.py y modificamos la función saludo para que cargue la plantilla. Aunque posteriormente lo haremos con cargadores vamos a empezar poco a poco y en este ejemplo lo haremos manualmente.

Lo primero que haremos es importar al comienzo del programa la clase Template y Context

views.py

from django.http import HttpResponse
import datetime
from django.template import Template, Context

# Vistas
def saludo(request):
    doc_externo = open("/home/chema/Cursos/DJANGO/Proyecto1/plantillas/plantilla.html")
    plantilla = Template(doc_externo.read())
    doc_externo.close()
    # Aunque no hay contenido dinámico, hay que crear el contexto.
    contexto = Context()
    # Renderizamos el contenido
    documento = plantilla.render(contexto)
    return HttpResponse(documento)

...
Si vamos al archivo de vistas, views.py, en vez de trabajar con texto incrustado lo vamos a hacer con una plantilla ya creada, para cargarla y renderizarla. 

Empezamos creando una variable, doc_externo, que utiliza el método open para cargar la plantilla. Tenemos que especificar la ruta donde encontrar el documento. (Ojo que para especificar la ruta hay que usar esta barra "/" sobretodo si estás en windows)

Una vez hecho esto creamos el objeto de tipo Template que asignare a una variable que puedes llamar como prefieras, plantilla en mi caso. Utilizamos .read() para leerla. Ya tenemos cargado el documento.

Y como lo tenemos cargado voy a cerrar el fichero para que no ocupe memoria con doc_externo.close().

Como el ejemplo es muy sencillo y no lleva contenido dinámico, ni información adicional la variable contexto es igual a la clase Context pero sin contenido. 

Para finalizar renderizamos el contenido.

Si ejecutamos el servidor y lo probamos con localhost/saludo/ nos debería funcionar.

Todo lo anterior es para tener la idea global de como funciona la carga de plantillas, ya que como veremos luego existen métodos más eficientes y sencillos de hacerlo, como veremos en el próximo post.


No hay comentarios:

Publicar un comentario