Programación Back-End

Unidad 2: Framework Back-End

Aplicación de modelos Django

Redactado por Criz
Publicado el 4 de junio de 2024 a las 22:57
Última actualización el 4 de junio de 2024 a las 22:57

Acciones rapidas
Editar
Siguiente
Previo

Django models: Una aplicación

Ahora vamos a aplicar lo que hemos aprendido, dejando la teórica, ahora vamos a la práctica.

Para ello, crearemos una galería de productos.

Setup

Realizamos los pasos que ya hemos visto en lo que va de la asignatura...

  1. Creamos un entorno virtual de Python.
  2. Activamos el entorno virtual de Python.
  3. Instalamos Django.
  4. Creamos un proyecto Django.
  5. Realizamos la configuración básica de Django.
    • Configuración del proyecto.
    • Configuración de templates.
    • Configuración de static.
    • Configuración de i18n.
  6. Creamos una aplicación en nuestro proyecto Django. (tienda)
    • Registramos nuestra aplicación en el proyecto.
    • Creamos una vista de inicio para nuestra aplicación.
    • Configuramos las urls de nuestra aplicación.

Creación del modelo

Ahora, creamos nuestro modelo dentro de ProyectoDjango/tienda/models.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Producto(models.Model):
    slug = models.SlugField()
    nombre = models.CharField(max_length=100)
    descripcion = models.TextField()
    stock = models.PositiveSmallIntegerField()
    precio = models.PositiveSmallIntegerField()
    modificacion = models.DateTimeField(auto_now=True, auto_now_add=False)
    creacion = models.DateTimeField(auto_now=False, auto_now_add=True)
    def __str__(self):
        return str("[{}] {} {}".format(self.slug, self.nombre, self.stock))

Migramos

La migración es un proceso automático que crea las tablas de nuestros modelos, o modificaciones que hayamos realizado a nuestros modelos ya creados.
Para ello, la aplicación debe estar registrada en settings.py de nuestro proyecto.

Para realizar la migración, en la consola:

Luego, migramos:

Si abrimos nuestro archivo db.sqlite3 con DB Browser, podremos observar que se han creado todas las tablas necesarias, incluyendo nuestra tabla Producto (tienda_producto).

Shell de manage.py

Para la agregar datos, modificar, listar y eliminar datos, podemos usar la shell de manage.py. Esto se logra mediante el comando:

Deberíamos ver que la consola tiene el estado:

1
2
3
4
Python 3.10.0 (tags/v3.10.0:b494f59, Oct  4 2021, 19:00:18) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

El >>> nos dice que está listo para recibir código Python.

Para agregar productos, primero debemos importar el model.

Nótese que la ubicación del script es en el directorio en donde manage.py se encuentra.

Entonces, importamos nuestro modelo, teniendo en cuenta el nombre de la aplicación en la que se encuentra:

1
from tienda.models import Producto

Una vez ya importado, podemos comenzar a crear registros, mediante bulk_create() podemos insertar más de un registro a la vez:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Producto.objects.bulk_create(
    [
        Producto(
            slug="filorte",
            nombre="Un pico de este porte",
            descripcion="Muy grande",
            stock=4,
            precio=15000,
        ),
        Producto(
            slug="martillo-de-cristal",
            nombre="Martillo de cristal",
            descripcion="Martillo de cristal de 3 golpes",
            stock=8,
            precio=12000,
        ),
        Producto(slug="pila-de-corriente-alterna",
            nombre="Bateria AC",
            descripcion="Bateria tipo pila de 12V AC",
            stock=19,
            precio=2790
        ),
    ]
)

No hace falta usar la función save(). Ya que es instantáneo. Por lo que, debes revisar bien tus comandos.

Vistas para nuestra galería

La idea es generar una vista en donde se muestren todos los productos. Y otra vista para ver un producto en específico.

Entonces, manos a la obra!

Creación de la vista galería general

Primero creamos la vista de galería de productos.
En tienda/views.py importamos nuestro modelo:

1
from .models import Producto

Nótese que el . en .models es para referenciar el módulo actual, ósea, nuestra aplicación actual.
También es válido (y recomendable) usar from tienda.models import Producto.
Pero es para que sepas que, si es relativo a sí mismo, podemos omitir el nombre.

Ahora, escribimos la vista:

1
2
3
4
5
def index(request):
    #  👇 variable                👇 devuelve todos los productos
    productos = Producto.objects.all()
    #                                             👇 llave  -  👇 valor
    return render(request, "tienda/index.html", {"productos": productos})

Definición de las templates

Creamos nuestro template base.html dentro de templates/:

Y ahora generamos el archivo index.html dentro de templates/tienda/:

 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
{% extends 'base.html' %}

{% block title %}Tienda{% endblock %}

{% block content %}
<div class="container">
<!-- primero verificamos que en nuetro contexto exista la llave 'productos' -->
{% if productos %}
    <div class="row">
        <!-- usamos un ciclo For de Python de toda la vida -->
        {% for producto in productos %}
        <div class="col-md-3">
            <div class="card" style="width: 18rem;">
                <!-- mostramos las variables mediante el uso de dobe llaves, que es para evaluar una variable -->
                <div class="card-body">
                    <h5 class="card-title">{{ producto.nombre }}</h5>
                    <p class="card-text">
                        {{ producto.descripcion }}
                        <br>
                        <strong>Stock</strong> {{ producto.stock }}
                        <br>
                        <strong>Precio Unitario</strong> $ {{ producto.precio }}
                        <br>
                    </p>
                </div>
            </div>
        </div>
        <!-- siempre tenemos que terminar los tags -->
        {% endfor %}
    </div>
{% endif %}
</div>
{% endblock %}

Y listo, tenemos la galería de productos completa.

Creación de la vista para productos específicos

Ahora, para ver un producto en específico, sabemos que tenemos que hacer tres cosas:

  1. Crear la vista.
  2. Crear la ruta.
  3. Modificar el template

Creando la vista

En el mismísimo hogar/views.py, creamos una nueva vista:

1
2
3
4
5
6
7
#                     👇 recibimos un parametro uid (el slug del Producto)
def producto(request, uid):
    #                                  👇 buscamos el producto cuyo slug sea el que se nos ha dado
    producto = Producto.objects.get(slug=uid)
    #                                             👇 singular (solo es un producto)
    return render(request, "tienda/index.html", {"producto":producto})
    # notese que si le ponemos productos (con s final) tendremos problemas para modificar la template

Nótese que la función producto recibe uid, esto se debe definir en la ruta.

Creando la ruta

Tenemos que definir que una vista puede recibir parámetros a través de la URL. Para ello vamos a hogar/urls.py y definimos una nueva ruta:

1
2
3
4
5
6
urlpatterns = [
    ...
    #       👇 tipo de dato    👇 vista (funcion que la recibe)
    path('<slug:uid>/', app.producto, name="producto"),
    #            👆 nombre de la variable      👆 para usar el tag 'url'
]

Ahora que la definimos, debemos hacer una modificación a la template templates/hogar/index.html.

Modificando la template

Modificamos la template templates/hogar/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
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
{% block content %}
<div class="container">
<!-- vemos si son todos los productos -->
{% if productos %}
    <div class="row">
        {% for producto in productos %}
        <div class="col-md-3">
            <div class="card" style="width: 18rem;">
                <div class="card-body">
                    <h5 class="card-title">{{ producto.nombre }}</h5>
                    <p class="card-text">
                        {{ producto.descripcion }}
                        <br>
                        <strong>Stock</strong> {{ producto.stock }}
                        <br>
                        <strong>Precio Unitario</strong> $ {{ producto.precio }}
                        <br>
                        <!-- un link para ir al la vista de ese producto -->
                        <a class="btn btn-primary" href="{% url 'tienda:producto' producto.slug %}">Ver</a>
                        <!--                                  nombre de la vista | argumento (uid) -->
                        <!-- 
                            USAMOS EL TAG url
                            que acepta el parametro uid que definimos como un argumento.
                         -->
                    </p>
                </div>
            </div>
        </div>
        {% endfor %}
    </div>
<!-- si no son todos los productos, entoces vemos si es un producto -->
{% elif producto %}
<h2>{{ producto.nombre }}</h2>
<h4>{{ producto.descripcion }}</h4>
<br>
<div class="row text-center">
    <div class="col-md-2">
        <h5>Cantidad</h5>
        {{ producto.stock }}
    </div>
    <div class="col-md-2">
        <h5>Precio Unitario</h5>
        {{ producto.precio }}
    </div>
</div>
{% endif %}
</div>
{% endblock %}

Y listo. Ahora tenemos la galería general para todos los productos y una vista para un producto en específico.

TEST TIME

Cuando vas a la URL http://127.0.0.1:8000/ se debería ver así:

Y, si vas a la url http://127.0.0.1:8000/martillo-de-cristal/ deberias ver algo asi:

Si se puede usar la id (<int:uid>) del producto. Pero no queda "lindo", es un numero vacío, en cambio el slug provee información clara de lo que estas solicitando.

Ya tiene lo básico. Ahora vas a sufrir.


Siguiente
Previo