En esta página:
Demo Github
En la parte anterior trabajamos en la creación de la rutas, estas son importantes para poder cargar las vistas Crear, Leer, Actualizar y Eliminar (Create, Read, Update y Delete). También creamos los templates para cada vista, es decir los archivos HTML para las vistas del sistema CRUD. Asimism instalamos y configuramos los paquetes Bootstrap 5 y Django Widget Tweaks. En esta última parte terminamos con eltutorial Como Crear Un CRUD con Django 4 (Python 3.11) y Bootstrap 5 – Parte 5 (Final)
Partes
Antes de continuar te invito a leer los siguientes artículos:
-
- Que es Django, Historia y tu primer Hola Mundo (Corregido: 31-05-2019)
- Conceptos Iniciales para desplegar Django
- Como usar Django y React JS (Método Manual, no Librería)
- Como crear un CRUD con Django 2 y Bootstrap 4 – Parte 1 (Python 3.7)
- 5 Servicios de Hosting VPS ideales para publicar un Proyecto Creado con Django
- Como Integrar Firebase en Django 3.0.7 – Parte 1
- Como Crear un Enlace de Descarga en Django
- 7 Proyectos que han sido Creados con Django Framework
- Como Crear una API REST con Django 3.1.1 + Consumir Datos en una Aplicación Android – Parte 1
- Puedes leer más en la categoría Django
Asimismo, te invito a escuchar el Podcast: “Si No Tienes Experiencia Para Un Puesto De Trabajo, Créala !” y “¿ Se Debe Escuchar Música Mientras Se Programa ?” (Anchor Podcast):
Spotify: | Sound Cloud: | Apple Podcasts | Anchor Podcasts |
Bien ahora continuemos con el Post: Como Crear Un CRUD con Django 4 (Python 3.11) y Bootstrap 5 – Parte 5 (Final).
En la vista principal voy a mostrar una tabla HTML en donde se listarán los registros o jugos desde la base de datos, colocaré una tabla HTML de Bootstrap 5 con las columnas Nombre, Precio, Stock, Imagen y Acciones.
Dentro de la columna Acciones colocaré 3 botones que son Ver, Editar y Eliminar para cada registro o jugo.
En la Parte 4 de este tutorial creamos 4 archivos HTML dentro de nuestra carpeta templates que son actualizar.html, crear.html, detalles.html e index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/cruddjango4 ├── /cruddjango4 ├── /jugos ├── /__pycache__ ├── /migrations ├── /static ├── /templates ├── /jugos ├── actualizar.html // Creamos este archivo ├── crear.html // Creamos este archivo ├── detalles.html // Creamos este archivo ├── index.html // Creamos este archivo ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── tests.py ├── views.py ├── db.sqlite3 ├── manage.py ├── /miev |
Entonces vamos a usar esos archivos HTML para crear las vistas con Bootstrap 5 a continuación.
Vistas HTML con Bootstrap 5
Para poder crear las vistas HTML debemos de instanciar la librería o core de Bootstrap 5 junto a su archivo de estilos CSS, todo esto debemos hacerlo en cada archivo HTML de nuestro Sistema CRUD, lo colocamos entre las etiquetas <head></head>
1 2 3 4 5 6 7 8 9 10 11 |
<head> {# Cargamos la librería #} {% load django_bootstrap5 %} {# CSS Bootstrap #} {% bootstrap_css %} </head> |
Ahora defino la configuración de la carpeta STATIC_URL en nuestro archivo settings.py
1 2 3 4 |
# Esta configuración se encuentra dentro del archivo settings.py STATIC_URL = '/static/' |
Por medio de STATIC_URL le decimos a Django que usaremos la carpeta /static/ para almacenar nuestros archivos CSS, JS y las imágenes de cada registro o jugo que subamos a nuestra Base de Datos.
En el archivo HTML colocamos entre las etiquetas <head></head> la configuración de STATIC_ROOT, lo puedes colocar debajo de la llamada que hicimos al core y archivo CSS de Bootstrap 5:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<head> {# Cargamos la librería #} {% load django_bootstrap5 %} {# CSS Bootstrap #} {% bootstrap_css %} </head> {# Archivos #} {% load static %} <!-- STATIC_URL --> </head> |
Ahora pasemos a crear las vistas HTML con Bootstrap 5 para las operaciones CRUD.
Listar Jugos (Página Principal)
Comenzaré listando los jugos en una tabla HTML con Bootstrap 5, abre el archivo index.html y agrega lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<table class="table table-striped table-hover"> <thead> <tr> <th width="35%">Nombre</th> <th>Precio</th> <th>Stock</th> <th>Imagen</th> <th>Acciones</th> </tr> </thead> <tbody> <!-- Recorremos los objetos o registros que tenemos en nuestra tabla 'jugos' y los listamos --> {% for jugo in object_list %} <tr> <td>{{ jugo.nombre }}</td> <td>{{ jugo.precio }}</td> <td>{{ jugo.stock }}</td> <td><img src="{% static 'uploads/'%}{{jugo.img}}" alt="{{jugo.nombre}}" class="img-fluid" width="7%"></td> <td> <!-- Usaremos un formulario que realizará la tarea de eliminar un registro o jugo desde la misma tabla HTML --> <form method="POST" action="eliminar/{{jugo.id}}"> {% csrf_token %} <div class="btn-group"> <!-- Creamos 3 botones que son ver, Editar y Eliminar, nos sirven para gestionar nuestros registros o jugos --> <a href="detalle/{{jugo.id}}" title="Ver" type="button" class="btn btn-success">Ver </a> <a href="editar/{{jugo.id}}" title="Editar" type="button" class="btn btn-primary">Editar </a> <button class="btn btn-danger" onclick="return eliminar();" type="submit"> Eliminar </button> </div> </form> </td> </tr> {% endfor %} </tbody> </table> |
Arriba de la tabla HTML agrego un botón Crear para ingresar nuevos registro a nuestra Base de Datos:
1 2 3 4 5 |
<div align="left" class="btn_crear mb-3"> <a href="crear" type="button" class="btn btn-primary">Crear</a> </div> |
Entonces con esto obtenemos nuestra vista principal (index.html) con el listado respectivo de los jugos o registros.
Y cada ves que en la tabla HTML aparece un registro o jugo nuevo, el sistema le asigna una tira de botones que son Ver, Editar y Eliminar:
Bien, pasaré a diseñar la vista HTML Crear.
Crear (Create)
Esta vista servirá para la creación de un nuevo registro o jugo, abro el archivo crear.html el cual lo cree en la parte 3 de este tutorial, este archivo se encuentra dentro de la carpeta templates y le agrego el siguiente formulario:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<form method="post" enctype="multipart/form-data"> # Pasamos el 'csrf_token' de seguridad para poder crear un nuevo registro {% csrf_token %} <!-- {{ form.as_p }} --> <div class="form-group"> <label for="nombre" class="txt_negrita">Nombre</label> {{ form.nombre|add_class:"form-control" }} <!-- Usamos la librería 'widget_tweaks' para crear esta caja de texto --> </div> <div class="form-group"> <label for="precio" class="txt_negrita">Precio</label> {{ form.precio|add_class:"form-control" }} <!-- Usamos la librería 'widget_tweaks' para crear esta caja de texto --> </div> <div class="form-group"> <label for="stock" class="txt_negrita">Stock</label> {{ form.stock|add_class:"form-control" }} <!-- Usamos la librería 'widget_tweaks' para crear esta caja de texto --> </div> <div class="form-group"> <label for="img" class="txt_negrita">Imagen</label> {{ form.img|add_class:"form-control mb-3" }} <!-- Usamos la librería 'widget_tweaks' para crear esta caja de texto --> </div> <button type="submit" class="btn btn-primary">Aceptar</button> <a href="./" type="submit" class="btn btn-primary">Cancelar</a> </form> |
Puedes ver en el código del archivo crear.html que estamos usando la librería widget_tweaks que instale en la Parte 4 de este tutorial, esta librería nos permite gestionar nuestros formularios creados mediante Vistas Genéricas de Django.
Bueno con esto tenemos nuestra vista crear.html con el formulario para ingresar un nuevo jugo o registro:
Ahora pasaré a crear la vista HTML Leer.
Leer (Read)
En esta vista vamos a mostrar los detalles de un archivo independientemente cada ves que el usuario haga clic en el botón Ver que se encuentra en la columna Acciones al lado de un determinado registro en la tabla HTML del archivo index.html
Entonces agrego el siguiente código HTML al archivo detalles.html que se encuentra en la carpeta templates, con este código imprimimos los objetos o datos con la información de un registro específico:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<h4>Detalles</h4> <p><span class="txt_negrita">Nombre:</span> <br> {{object.nombre}}</p> <p><span class="txt_negrita">Precio:</span> <br> {{object.precio}}</p> <p><span class="txt_negrita">Stock:</span> <br> {{object.stock}}</p> <p><span class="txt_negrita">Imagen:</span> <br> <img src="{% static 'uploads/'%}{{object.img}}" alt="{{object.nombre}}" class="img-fluid"> </p> <p><span class="txt_negrita">Creado:</span> <br> {{object.created_at}}</p> <p><span class="txt_negrita">Actualizado:</span> <br> {{object.updated_at}}</p> <!-- Botón para volver a la vista principal (Home) --> <a href="../" type="submit" class="btn btn-primary">Volver</a> |
Django envía el id del registro al archivo o template llamado detalles.html para mostrar los detalles de dicho registro, el envío de este id lo hace por la ruta jugos/detalle/<int:pk>
1 2 3 |
path('jugos/detalle/<int:pk>', JugoDetalle.as_view(template_name = "jugos/detalles.html"), name='detalles'), |
Esta ruta la definimos anteriormente en la Parte 4 de este tutorial, específicamente dentro del archivo urls.py
Con este tenemos nuestra vista Leer con los datos de un registro determinado:
Ahora pasaré a crear la vista HTML Actualizar.
Actualizar (Update)
En esta vista colocaré un formulario HTML para poder editar un registro determinado, dentro de cada elemento Django colocaremos los valores específicos de un registro o jugo.
Abro el archivo actualizar.html que se encuentra en la carpeta templates y agrego el siguiente código HTML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<form method="post" enctype="multipart/form-data"> {% csrf_token %} <!-- {{ form.as_p }} --> <div class="form-group"> <label for="nombre" class="txt_negrita">Nombre</label> {{ form.nombre|add_class:"form-control" }} <!-- Usamos la librería 'widget_tweaks' para crear esta caja de texto --> </div> <div class="form-group"> <label for="precio" class="txt_negrita">Precio</label> {{ form.precio|add_class:"form-control" }} </div> <div class="form-group"> <label for="stock" class="txt_negrita">Stock</label> {{ form.stock|add_class:"form-control" }} </div> <div class="form-group"> <label for="img" class="txt_negrita">Imagen</label> {{ form.img|add_class:"form-control mb-3" }} <p class="txt_negrita">Imagen Actual:</p> <img src="{% static 'uploads/'%}{{object.img}}" class="img-fluid" alt="{{object.nombre}}"> </div> <button type="submit" class="btn btn-primary">Aceptar</button> <a href="../" type="submit" class="btn btn-primary">Volver</a> </form> |
En la siguiente ruta para actualizar, le paso el id del registro que vamos a Editar o actualizar:
1 2 3 |
path('jugos/editar/<int:pk>', JugoActualizar.as_view(template_name = "jugos/actualizar.html"), name='actualizar'), |
Mediante la ruta anterior, Django nos envía al archivo actualizar.html los datos de un determinado registro y los coloca dentro del formulario listos para poder ser editados:
Por último trabajaremos en la vista HTML Eliminar, pero más que una vista es una función o tarea del sistema CRUD, veamosla mejor a continuación.
Eliminar (Delete)
En esta vista vamos a usar el archivo index.html que se encuentra dentro de la carpeta templates, en este archivo estamos listando todos los registros o jugos de la Base de Datos.
Dentro de la columna Acciones puedes ver en el código que he colocado un formulario, este formulario solo nos va servir para ejecutar la eliminación de un registro desde la misma tabla HTML donde listamos los registros:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<table class="table table-striped table-hover"> <thead> <tr> <th width="35%">Nombre</th> <th>Precio</th> <th>Stock</th> <th>Imagen</th> <th>Acciones</th> </tr> </thead> <tbody> {% for jugo in object_list %} <tr> <td>{{ jugo.nombre }}</td> <td>{{ jugo.precio }}</td> <td>{{ jugo.stock }}</td> <td><img src="{% static 'uploads/'%}{{jugo.img}}" alt="{{jugo.nombre}}" class="img-fluid" width="7%"></td> <td> <!-- Usaremos un formulario que realizará la tarea de eliminar un registro o jugo desde la misma tabla HTML --> <form method="POST" action="eliminar/{{jugo.id}}"> {% csrf_token %} <div class="btn-group"> <a href="detalle/{{jugo.id}}" title="Ver" type="button" class="btn btn-success">Ver </a> <a href="editar/{{jugo.id}}" title="Editar" type="button" class="btn btn-primary">Editar </a> <!-- Este botón ejecuta el formulario para eliminar un registro o jugo en la Base de datos --> <button class="btn btn-danger" onclick="return eliminar();" type="submit"> Eliminar </button> </div> </form> </td> </tr> {% endfor %} </tbody> </table> |
La idea es hacer la eliminación de los registros desde la misma página, no sería muy estético eliminar el registro en una nueva página HTML, salvo que tu proyecto lo requiera.
Entonces por seguridad antes de eliminar un registro, vamos a consultar al usuario si desea eliminar un registro, dentro de nuestro botón para enviar el formulario llamamos a la función Javascript eliminar();
1 2 3 4 5 |
<button class="btn btn-danger" onclick="return eliminar();" type="submit"> Eliminar </button> |
Cuando el usuario hace clic en el botón se muestra una alerta con el mensaje Eliminar Producto ?
La función eliminar(); la he creado con Javascript y la colocamos al final antes de cerrar la etiqueta </body> de nuestro archivo HTML llamado index.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<script type="text/javascript"> function eliminar() { var x = confirm("Eliminar Producto ?"); if (x) return true; else return false; } </script> </body> </html> |
Bien, cuando el usuario haga clic en el botón Eliminar de alguno de los registros que se encuentran en la columna Acciones de la tabla HTML, le lanzamos la alerta para que confirme la eliminación del registro:
De esta manera impedimos que el usuario borre por error alguno de sus registros.
Mensajes
En el archivo index.html van a recaer todos los mensajes de las operaciones Crear, Eliminar y Actualizar, es decir después de Insertar, Eliminar o Actualizar un registro o jugo de la Base de Datos, mostramos un mensaje para confirmar que dicha operación ha sido realizada Correctamente.
Abro el archivo index.html que se encuentra en la carpeta templates y agrega el siguiente código:
1 2 3 4 5 6 7 8 9 |
{% if messages %} <ul class="messages list-group mb-3"> {% for message in messages %} <li{% if message.tags %} class="{{ message.tags }} list-group-item list-group-item-primary"{% endif %}>{{ message }}</li> {% endfor %} </ul> {% endif %} |
Por ejemplo cuando el usuario Edite un registro o jugo, se le va mostrar un mensaje diciendo que la operación ha sido realizada correctamente, este mensaje también le va aparecer cuando Crea o Elimina un registro:
Ahora veremos la carpeta uploads, una carpeta importante para la subida de las imagenes.
La carpeta uploads
Debemos de crear una carpeta para las imágenes de cada Registro que el usuario crea, yo le pondré de nombre uploads a esta carpeta y la creamos dentro de la carpeta jugos > static > uploads
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
/cruddjango4 ├── /cruddjango4 ├── /jugos ├── /__pycache__ ├── /migrations ├── /static ├── /uploads # Creo esta carpeta ├── jn.jpg ├── /templates ├── /css ├── __init__.py ├── admin.py ├── apps.py ├── models.py ├── tests.py ├── views.py ├── db.sqlite3 ├── manage.py ├── /miev |
Con eso ya tenemos finalizado nuestro sistema CRUD.
Configuraciones Adicionales
Por favor te recomiendo revisar el archivo settings.py alojado en el Repositorio GitHub de este proyecto en donde esta toda la configuración que he realizado, pero debo destacar las siguientes configuraciones (He colocado comentarios para explicar que hace cada parte del código):
1 2 3 4 5 6 7 8 9 10 11 |
# La URL para los archivos Estáticos (CSS, JS, Imágenes, etc.) STATIC_URL = '/static/' # Las rutas para las imágenes de cada registro o jugo MEDIA_URL = '/jugos/' MEDIA_ROOT = os.path.join(BASE_DIR, 'jugos/static/uploads') # Activamos 'CookieStorage' que nos permite enviar los mensajes de respuesta al Crear, Eliminar y Actualizar un registro MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage' |
Bien, hasta aquí hemos terminado con este tutorial que consta de 5 partes y explico paso a paso como crear el sistema CRUD con Django 4 y Bootstrap 5.
He colocado una Demo al inicio de cada parte del tutoria, para que veas el sistema CRUD en acción, asimismo he colocado el código fuente en GitHub en la última parte del tutorial.
Nota (s)
- Los Pasos y opciones mencionadas en esta parte del tutorial pueden cambiar, esto no depende de nosotros, si no de los Desarrolladores que dan soporte a Django y Bootstrap, que suelen cambiar sus opciones de despliegue y configuración en futuras versiones.
- No olvides que debemos usar la Tecnología para hacer cosas Buenas por el Mundo.
Síguenos en nuestras Redes Sociales para que no te pierdas nuestros próximos contenidos.