Mostrando entradas con la etiqueta HttpResponse. Mostrar todas las entradas
Mostrando entradas con la etiqueta HttpResponse. Mostrar todas las entradas

martes, 28 de febrero de 2023

12.- Desarrollo Práctico de una aplicación. Creación Proyecto, Aplicación, Primeras vistas y Plantillas.

Vamos a crear una aplicación completa de Django y a la vez profundizando más en varios conceptos. La aplicación que crearemos tendrá cinco vistas:

  • Inicio
  • Servicios
  • Tienda 
  • Blog
  • Contacto
Todo lo que sigue ya lo hemos visto en capitulos previos, asi que no me detendré a comentarlo. Comenzaremos creando el proyecto con el nombre que queramos, en mi caso usaré PracticaDjango:


$ django-admin startproject PracticaDjango

Esto nos creará un directorio con la siguiente estructura:

PracticaDjango       > Directorio Padre 
    manage.py        > Archivo de gestión de Django.
    PracticaDjango --> Es un directorio

Es siguiente caso es crear la aplicación que gestionará la aplicación web. Así que entramos en el directorio padre y creamos la aplicación:

PracticaDjango$ python manage.py startapp Proyecto_web_app

Salida:

PracticaDjango       > Directorio Padre 
    manage.py        > Archivo de gestión de Django.
    PracticaDjango --> Es un directorio
    Proyecto_web_app > El directorio de la app recien creada.

Recuerda que una cosa es el proyecto y otra la aplicación. En Django dentro de un proyecto puedes tener muchas aplicaciones.

Ahora es un buen momento para verificar que nuestro proyecto funciona, así que vamos a la consola y ejecutamos el servidor:

PracticaDjango$ python manage.py runserver

Abrimos el navegador y entramos en localhost:8000 y si todo ha ido bien verás la siguiente pantalla:

pantalla inicio de Django

Seguidamente creamos de forma sencilla las vistas de cada una de las cinco url de la aplicación. Para ello vamos al archivo views.py y para hacer algunas pruebas importamos la clase HttpResponse.

PracticaDjango/Proyecto_web_app/views.py

from django.shortcuts import render, HttpResponse

# Create your views here.

def home(request):
    return HttpResponse('Home')

def servicios(request):
    return HttpResponse('Servicios')

def tienda(request):
    return HttpResponse('Tienda')

def blog(request):
    return HttpResponse('Blog')

def contacto(request):
    return HttpResponse('Contacto')

Ahora nos vamos a registrar las URLS. Importamos las vistas y luego registramos las direcciones.

PracticaDjango/PracticaDjango/urls.py

from django.contrib import admin
from django.urls import path
from Proyecto_web_app import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.home, name='home'),
    path('servicios/', views.servicios, name='servicios'),
    path('tienda/', views.tienda, name='tienda'),
    path('blog/', views.blog, name='blog'),
    path('contacto/', views.contacto, name='contacto'),
]

Volvemos a ejecutar el servidor, si lo hemos cerrado y probamos cada una de las url, para ver que todas las vistas funcionan.

Ej para la vista blog.

vista blog funcionando correctamente


Reorganización de las url para un mejor funcionamiento.


Hay que tener en cuenta que nosotros creamos un proyecto en Django y este puede tener varias aplicaciones. De igual forma es muy frecuente que una aplicación Django la puedas reaprovechar en diferentes proyectos. Hasta ahora registramos nuestras Urls dentro del archivo urls.py que estaba en PracticaDjango. Pero imaginaros si tuviéramos que registrar en el las urls, no de una única aplicación, sino de tres, cuatro o quince aplicaciones. En este caso este archivo tendría muchísimo código y nos seria complicado saber que urls son de una aplicación y cual de otra. Así que lo bueno es que las urls de cada aplicación estén dentro de su directorio. 

Para ello seguimos las instrucciones que ya nos indica Django en el archivo urls.py del Proyecto.

1.- Creamos un archivo llamado urls.py pero dentro de la aplicación.

2.- Luego dentro de ese archivo importamos el path

PracticaDjango/Proyecto_web_app/urls.py

from django.urls import path

3.- A continuación importamos las vistas de la aplicación.

PracticaDjango/Proyecto_web_app/urls.py

from django.urls import path
from . import views

4.- Tenemos que trabajar con la lista urlpatterns y para no tener que escribir tanto, vamos al url del proyecto, copiamos el urlpatterns y lo pegamos aquí. Lógicamente quitamos la vista admin que no corresponde a la aplicación, sino al proyecto.

PracticaDjango/Proyecto_web_app/urls.py

from django.urls import path
from Proyecto_web_app import views

app_name = "Proyecto_web_app"

urlpatterns = [
    path('', views.home, name='home'),
    path('servicios/', views.servicios, name='servicios'),
    path('tienda/', views.tienda, name='tienda'),
    path('blog/', views.blog, name='blog'),
    path('contacto/', views.contacto, name='contacto'),
]


'app_name' en Django se utiliza para definir un nombre único para la aplicación, evitando conflictos de nombres con otras aplicaciones que pudiéramos crear luego.

'name' se asigna a cada URL dentro de la aplicación y proporciona una etiqueta única para esta URL en nuestro proyecto.

Estos atributos nos ayudarán a a organizar y referenciar fácilmente las URLs en nuestro código y en las plantillas de Django.  Por ejemplo cuando más adelante tengamos que construir una URL en una plantilla en vez de usar una referencia absoluta para referirnos a la vista 'home' haremos referencia a ella como 'Proyecto_web_app:home'.

Y como hemos movido todas las vistas de la aplicación, en el archivo urls.py del PROYECTO quitamos todo lo que hemos movido y dejamos solo el admin. Quitamos también la importación de las vistas. En definitiva lo dejamos como estaba al principio. Solo nos falta enlazar el url del proyecto con el url de la aplicación, lo haremos a través del path como nos pone Django en la documentación de este mismo archivo, usando el comando 'include' que previamente habremos de importar.

PracticaDjango/PracticaDjango/ulrs.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls), 
    path('proyecto_web_app/', include('Proyecto_web_app.urls')), 
]

Llegado este punto, tenemos que comprobar que funcionan bien las urls teniendo en cuenta el path que acabamos de escribir. Para acceder a las vistas tendríamos que hacer lo siguiente. Vamos a ver como acceder a una con un ejemplo.

aceso a url tienda
Pero al hacer esto, hemos complicado un poco la url porque tenemos que agregar 'proyecto_web_app', que es el nombre de nuestro proyecto. Si queremos teclear las urls como antes, que sin poner nada nos llevaba a las vistas, tenemos que ir al urls del proyecto y en el path tenemos que dejar vacía la raíz para que no haya que poner nada y así, funcionaría como al principio.

PracticaDjango/PracticaDjango/urls.py 

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('Proyecto_web_app.urls')),  
]

url acortada de la aplicación

Plantillas de las vistas.


Nos vamos a la carpeta de la aplicación y creamos una carpeta llamada 'templates' y dentro de esta carpeta crearemos otra con el nombre también de la aplicación que será donde depositaremos las plantillas html. Tenemos que crear una plantilla para cada una de las vistas. Vamos a hacer una como ejemplo para la vista inicio pero tenemos que crear otras iguales para el resto.

PracticaDjango/Proyecto_web_app/templates/Proyecto_web_app/home.html

<!DOCTYPE html>
<html lang="en">
<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>Home</title>
</head>
<body>
    Home
</body>
</html>
Ahora debemos modificar el archivos de las vistas de la aplicación para que renderice las plantillas que habremos creado. Pero para que esto funcione es IMPORTANTE registrar nuestra aplicación. Tenemos que ir al archivo settings.py del proyecto y el la lista de INSTALLED_APPS tenemos que registrar la aplicación.

PracticaDjango/PracticaDjango/settings.py

...
# Application definition

INSTALLED_APPS = [
    # Nuestras aplicaciones.
    'Proyecto_web_app.apps.ProyectoWebAppConfig',
    # Aplicaciones por defecto.
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]
...

Podemos aprovechar este mismo archivo para modificar nuestra hora local (TIME_ZONE) y el idioma (LANGUAGE_CODE) como ya vimos en el capitulo 1.

Después de lo anterior, ya solo nos queda modificar el archivo de las vistas de la aplicación para que se rendericen cada una de las vistas cuando se llame a la url correspondiente.

PracticaDjango/Proyecto_web_app/views.py

from django.shortcuts import render, HttpResponse

# Create your views here.

def home(request):
    return render(request, 'Proyecto_web_app/home.html')

def servicios(request):
    return render(request, 'Proyecto_web_app/servicios.html')

def tienda(request):
    return render(request, 'Proyecto_web_app/tienda.html')

def blog(request):
    return render(request, 'Proyecto_web_app/blog.html')

def contacto(request):
    return render(request, 'Proyecto_web_app/contacto.html')

miércoles, 7 de diciembre de 2022

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

 ¿Te pierdes entre tantos temas? 📚✨ Descubre todo lo que ofrece este blog en un solo vistazo [👉 Ver índice completo]

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.

Próximo. Post 3.- Plantillas, variables y propiedades en la plantilla.