Skip to content

Creación de Modelos

Los modelos hacen referencia a las tablas del diseño de su base de datos. Para este caso asumimos el siguiente diseño.

Antes de crear los modelos de la aplicación es necesario que configuremos nuestra base de datos.

Especificación de la base de datos

Primero se debe instalar las extensiones en Django que permiten comunicarse con el motor de la base de datos.

Para este caso utilizaremos MySql, por lo cual instalamos:

mysqlclient

python3 -m pip install mysqlclient

En caso que se genere algun error probar con la instalación de la siguiente manera:

sudo apt-get install libmysqlclient-dev
sudo apt install pkg-config

Y luego intentar nuevamente

python3 -m pip install mysqlclient

Éste es también el punto donde normalmente especificarías la base de datos a utilizar en el proyecto --- tiene sentido usar la misma base datos para desarrollo y producción donde sea posible, para evitar diferencias menores en el comportamiento. Puedes encontrar información sobre las diferentes opciones de bases de datos en Databases (Django docs).

sitealmacen/sitealmacen/settings.py - Actualizar con el siguiente código.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'almacen2022_mysql',
        'USER': 'root',
        'PASSWORD': 'MiNiCo57**',
        'HOST': 'localhost',
        'PORT': '3306'

    }
}

Esto nos indica que procedemos a varios procesos.

  • Instalar el motor de la base de datos que para este caso es MySql.

    https://docs.microsoft.com/en-us/windows/wsl/tutorials/wsl-database

  • Una vez instalado el motor debemos iniciar dicho motor.

    Abrimos la terminal de Ubuntu WSL y escribimos.

    sudo /etc/init.d/mysql start

    Si aparece este mensaje, quiere decir que ya esta inicializado.

    * Starting MySQL database server mysqld

  • Crear la base de datos indicada: 'NAME': 'almacen2022_mysql', para ello, en la terminal de Ubuntu WSL ingresar

    sudo mysql -u root -p

    Y luego la contraseña.

    Si aparece en la terminal

    mysql> Indica que ya entró al motor de MySQL.

    Luego realice:

    show databases; Para mostrar las bases de datos que tiene creadas

    create database almacen2022_mysql;

    Debe aparecer en pantalla, para indicar que ha sido creada.

    Query OK, 1 row affected (0.01 sec)

Ya podemos probar realizando las migraciones, sin aun haber realizado los modelos. Esto es debido a que Django ya trae unos modelos pre establecidos.

Para ello, migramos de la siguiente manera:

En la ventana de terminal del proyecto en Visual Studio Code, recordemos que debe estar activa la unidad virtual y ubicados en la carpeta del proyecto sitealmacen. tal como se muestra.

(.venv) ubuntu@PortatlJQ:~/appsweb/clasesdlloweb/backdjango/2022iisem/sitealmacen$

Escribimos lo siguiente:

python3 manage.py makemigrations => Crea las migraciones

python3 manage.py migrate ==> Crea la base de datos físicamente, de acuerdo a las migraciones actuales.

Podemos probar en la terminar de Ubuntu, con el motor de MySQL abierto, para que nos muestre las tablas generadas en la base de datos que fueron creadas automáticamente, con la siguiente instrucción:

use almacen2022_mysql; ==> Para entrar a la base de datos

show tables; ==> Para mostrar las tablas de la base de datos.

Dando como resultado:

+-----------------------------+
| Tables_in_almacen2022_mysql |
+-----------------------------+
| auth_group                  |
| auth_group_permissions      |
| auth_permission             |
| auth_user                   |
| auth_user_groups            |
| auth_user_user_permissions  |
| django_admin_log            |
| django_content_type         |
| django_migrations           |
| django_session              |
+-----------------------------+
10 rows in set (0.00 sec)

Código de los Modelos

Aplicación Clientes

Los códigos de los modelos se realizan dentro de cada aplicación, que para este caso en particular se crearían en Apps/clientes/models.py de la siguiente manera:

En este caso tomaremos la tabla de clientes dentro de la aplicación correspondiente

Modelo de Cliente

from django.db import models

# Create your models here.


class Cliente(models.Model):
    nombreCliente = models.CharField(max_length=100, help_text="Ingrese el Nombre del Cliente")
    direccionCliente = models.CharField(max_length=100, help_text="Ingrese la Direccion del Cliente")
    telefonoCliente = models.CharField(max_length=12, help_text="Ingrese el Telefono del Cliente")
    correoCliente = models.EmailField(max_length=100, help_text="Ingrese el Correo del Cliente")
    passwordCliente = models.CharField(max_length=100, help_text="Ingrese el Password del Cliente")

    def __str__(self):
        return self.nombreCliente

    class Meta:
        verbose_name = "cliente"
        verbose_name_plural = "clientes"

Cada modelo obedece a una clase que hereda o extiende de la clase models.Model, la cual debemos importar.

Cada campo o atributo del modelo, para este caso Cliente posee Nombre, Tipo y Argumento de los campos.

Tipo de los Campos

El tipo del campo pueden ser (Numérico, Fecha, Boolean, entre otros). Para saber todos los tipos de los campos: TIPOS DE CAMPOS

Los siguientes tipos de campos comunes:

NOMBRE DEL CAMPO DESCRIPCIÓN
AutoField Es un IntegerField que se incrementa automáticamente.
BigAutoField Es un entero de 64 bits, muy parecido a un AutoField, excepto que se garantiza que se ajusta a los números del 1 al 9223372036854775807.
BigIntegerField Es un número entero de 64 bits, muy parecido a un IntegerField, excepto que se garantiza que se ajusta a números de -9223372036854775808 a 9223372036854775807.
BinaryField Un campo para almacenar datos binarios sin procesar.
BooleanField Un campo verdadero / falso. El widget de formulario predeterminado para este campo es CheckboxInput.
CharField Es una fecha, representada en Python por una instancia de datetime.date.
DateField Una fecha, representada en Python por una instancia de datetime.date
Se utiliza para la fecha y la hora, representada en Python por una instancia de datetime.datetime.
DecimalField Es un número decimal de precisión fija, representado en Python por una instancia Decimal.
DurationField Un campo para almacenar períodos de tiempo.
EmailField Es un CharField que verifica que el valor sea una dirección de correo electrónico válida.
FileField Es un campo de carga de archivos.
FloatField Es un número de punto flotante representado en Python por una instancia flotante.
ImageField Hereda todos los atributos y métodos de FileField, pero también valida que el objeto cargado es una imagen válida.
IntegerField Es un campo entero. Los valores de -2147483648 a 2147483647 están seguros en todas las bases de datos compatibles con Django.
GenericIPAddressField Una dirección IPv4 o IPv6, en formato de cadena(por ejemplo, 192.0.2.30 o 2a02: 42fe :: 4).
NullBooleanField Como BooleanField, pero permite NULL como una de las opciones.
PositiveIntegerField Como un IntegerField, pero debe ser positivo o cero(0).
PositivoSmallIntegerField Como PositiveIntegerField, pero solo permite valores bajo un cierto punto(dependiente de la base de datos).
SlugField Slug es un término periodístico. Una slug es una etiqueta corta para algo, que contiene solo letras, números, guiones bajos o guiones. Generalmente se utilizan en URL.
SmallIntegerField Es como un IntegerField, pero solo permite valores bajo un cierto punto(dependiente de la base de datos).
TextField Un campo de texto grande. El widget de formulario predeterminado para este campo es un área de texto.
TimeField Una hora, representada en Python por una instancia de datetime.time.
URLField Un CharField para una URL, validado por URLValidator.
UUIDField Un campo para almacenar identificadores únicos universales. Utiliza la clase UUID de Python. Cuando se usa en PostgreSQL, esto se almacena en un tipo de datos uuid, de lo contrario en un char(32).

Argumento de los Campos

Los siguientes argumentos son comunes a la mayoría de los tipos de campo y pueden usarse al declararlos:

  • max_length=20 --- Establece que la longitud máxima del valor de este campo es 20 caracteres.

  • help_text="Enter field documentation" --- proporciona una etiqueta de texto para mostrar que ayuda a los usuarios a saber qué valor proporcionar cuando un usuario ha de introducirlo via un formulario HTML.

  • help_text: Proporciona una etiqueta de texto para formularios HTML (ej. en el sitio de Administración), tal como se describe arriba.

  • verbose_name: Nombre de fácil lectura que se usa en etiquetas para el campo. Si no se especifica, Django inferirá el valor por defecto del verbose name a partir del nombre del campo.

  • default: Valor por defecto para el campo. Puede ser un valor o un callable object (objeto que puede ser llamado como una función), en cuyo caso el objeto será llamado cada vez que se cree un nuevo registro.

  • null: Si es True, Django guardará valores en blanco o vacíos como NULL en la base de datos para campos donde sea apropiado (un CharField guardará una cadena vacía en su lugar). Por defecto es False.

  • blank: Si es True, se permite que el campo quede en blanco en tus formularios. El valor por defecto es False, lo que significa que la validación de formularios de Django te forzará a introducir un valor. Con frecuencia se usa con null=True, porque si vas a permitir valores en blanco, también querrás que la base de datos sea capaz de representarlos de forma apropiada.

  • choices: Un grupo de valores de selección para este campo. Si se proporciona, el widget correspondiente por defecto del formulario será una caja de selección con estos valores de selección en vez del campo de texto estándar.

  • primary_key: Si es True, establece el campo actual como clave primaria para el modelo (Una clave primaria es una columna especial de la base de datos, diseñada para identificar de forma única todos los diferentes registros de una tabla). Si no se especifica ningún campo como clave primaria, Django añadirá automáticamente un campo para este propósito.

Métodos

Un modelo puede tener también métodos

Minimamente, en cada modelo deberías definir el método estándar de las clases de Python __str__() para devolver una cadena de texto legible por humanos para cada objeto. Esta cadena se usa para representar registros individuales en el sitio de administración (y en cualquier otro lugar donde necesites referirte a una instancia del modelo). Con frecuencia éste devolverá un título o nombre de campo del modelo.

def __str__(self):
        return self.nombre

Recuerde que self.nombre ==> self, indica que estamos en una función dentro de una clase, es decir un método y nombre hace referencia a la propiedad o variable de la clase.

Metadatos

Puedes declarar metadatos a nivel de modelo para tu Modelo declarando class Meta, tal como se muestra.

class Meta:
        verbose_name = "cliente"
        verbose_name_plural = "clientes"

La forma en que aparecen los modelos en el admin que genera Django.

Una vez definido el modelo, procedemos a crear las migraciones y la generación física de la base de datos, ingresamos en la terminal de visual studio code. (Con el ambiente virtual activado)

python3 manage.py makemigrations
python3 manage.py migrate

Aplicación Productos

Los códigos de los modelos se realizan dentro de cada aplicación, que para este caso en particular se crearían en Apps/productos/models.py de la siguiente manera:

Cuando se presentan varias tablas, primero se toma en consideración las tablas que no tienen llaves foráneas.

Modelo de tipoproductos y productos

from django.db import models

# Create your models here.

class TipoProducto(models.Model):
    nombre = models.CharField(max_length=50, verbose_name="Nombre")

    def __str__(self):
        return self.nombre

    class Meta:
        verbose_name = "tipo producto"
        verbose_name_plural = "tipo productos"


class Producto(models.Model):
    nombre = models.CharField(max_length=50, verbose_name="Nombre")
    marca = models.CharField(max_length=50, verbose_name="Marca")
    precio = models.FloatField(verbose_name="Precio")
    stockmin = models.IntegerField(verbose_name="Stock Minimo")
    cantidad = models.IntegerField(verbose_name="Cantidad")
    tipoproducto = models.ForeignKey(TipoProducto,
                                    null=True,
                                    blank=True,
                                    on_delete=models.CASCADE)

    def __str__(self):
        return self.nombre

    class Meta:
        verbose_name = "producto"
        verbose_name_plural = " productos"

Una vez definido el modelo, procedemos a crear las migraciones y la generación física de la base de datos, ingresamos en la terminal de visual studio code. (Con el ambiente virtual activado)

python3 manage.py makemigrations
python3 manage.py migrate

En este modelo se aprecia que relacionamos las tablas asociadas a las clases de TipoProducto y Producto, ambas se encuentran en el mismo archivo.

Como es una relación de uno a muchos, en donde se indica en la tabla de productos, evidenciando que pueden existir muchos tipos de productos en la tabla productos. Por lo que se concreta en:

tipoproducto = models.ForeignKey(TipoProducto,

null=True,

blank=True,

on_delete=models.CASCADE)

Aplicación Ventas

Los códigos de los modelos se realizan dentro de cada aplicación, que para este caso en particular se crearían en Apps/ventas/models.py de la siguiente manera:

Cuando se presentan varias tablas, primero se toma en consideración las tablas que no tienen llaves foráneas.

Modelo de ventas y producto_ventas

from django.db import models
from django.utils.timezone import now
from django.contrib.auth.models import User
from Apps.clientes.models import Cliente
from Apps.productos.models import Producto

# Create your models here.

class Venta(models.Model):
    fecha = models.DateField(default=now, verbose_name="Fecha Actual")
    descuento = models.DecimalField(max_digits=8, decimal_places=2, verbose_name="Descuento")
    total = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Total")
    subtotal = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="Sub Total")
    usuario= models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="Usuario")
    producto = models.ManyToManyField(Producto, through='VentaProducto', verbose_name="VentaProducto")
    created = models.DateTimeField(auto_now=True, verbose_name="Fecha de Creacion")
    updated = models.DateTimeField(auto_now=True, verbose_name="Fecha de Edicion")
    cliente = models.ForeignKey(Cliente,
                                    null=True,
                                    blank=True,
                                    on_delete=models.CASCADE)

    class Meta:
        verbose_name = "venta producto"
        verbose_name_plural = "Ventas Productos"


class VentaProducto(models.Model):
    producto = models.ForeignKey(Producto, on_delete=models.CASCADE, verbose_name="Producto")
    venta = models.ForeignKey(Venta, on_delete=models.CASCADE, verbose_name="Venta")
    fechaVenta = models.DateTimeField(auto_now=True, verbose_name="fecha")
    precio = models.IntegerField(verbose_name="Precio")
    cantidad = models.IntegerField(verbose_name="Cantidad")
    total = models.FloatField(verbose_name="Total")

Una vez definido el modelo, procedemos a crear las migraciones y la generación física de la base de datos, ingresamos en la terminal de visual studio code. (Con el ambiente virtual activado)

python3 manage.py makemigrations
python3 manage.py migrate

En este modelo se aprecia que relacionamos las tablas asociadas a las clases de usuarios y ventas, estas clases se encuentran en diferentes archivos, por cuanto obliga a importar dicha clase.

from django.contrib.auth.models import User

y luego relacionamos

usuario= models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="Usuario")

Como es una relación de uno a muchos, en donde se indica en la tabla de ventas, evidenciando que pueden existir muchos usuarioss en la tabla ventas.

También relacionamos las tablas asociadas a las clases de productos y ventas, estas clases se encuentran en diferentes archivos, por cuanto obliga a importar dicha clase.

from Apps.productos.models import Producto

Y luego relacionamos

producto = models.ManyToManyField(Producto, through='VentaProducto', verbose_name="VentaProducto")

Como es una relación de muchos a muchos, se procede a crear una nueva nueva tabla, que en este caso es un nueva clase denominada en el atributo through='VentaProducto .

En esta nueva clase se pueden agregar campos adicionales que usted considere en esta nueva tabla.

class VentaProducto(models.Model):

producto = models.ForeignKey(Producto, on_delete=models.CASCADE, verbose_name="Producto")

venta = models.ForeignKey(Venta, on_delete=models.CASCADE, verbose_name="Venta")

fechaVenta = models.DateTimeField(auto_now=True, verbose_name="fecha")

precio = models.IntegerField(verbose_name="Precio")

cantidad = models.IntegerField(verbose_name="Cantidad")

total = models.FloatField(verbose_name="Total")