logo cosasdedevs

Cómo utilizar el proxy model de Django

Cómo utilizar el proxy model de Django

My Profile
Feb 16, 2020

Hoy quiero volver a hablar de los modelos en Django, en el anterior post deste framework, hablabamos de como customizar el manager, podéis verlo en mi tutorial sobre como customizar el manager de un modelo en Django. Para esta vez vamos a utilizar una forma menos "invasiva" a la hora de extender la funcionalidad de nuestros modelos usando proxy models.

Pero primero ¿Qué es un Proxy Model?

Es un tipo de herencia del modelo principal sin tener que crear una nueva tabla. Se utiliza para añadir nuevas funcionalidades a un modelo existente, como por ejemplo modificar el orden al realizar una query, unir datos, etc, sin modificar el esquema de la tabla de datos de la que extendemos. Para más info: https://docs.djangoproject.com/en/3.0/topics/db/models/

Bueno y ahora que ya sabemos esto, vamos a crear un ejemplo que es donde se ve realmente su funcionamiento y como se puede aplicar. Para ello he creado un proyecto en Django y un app llamada Contactos que tendrá un modelo con el siguiente código:

from django.db import models


class Contacto(models.Model):
    nombre = models.CharField(max_length=50)
    apellidos = models.CharField(max_length=100)
    fecha_nacimiento = models.DateField()

Como véis es he creado un modelo bastante sencillo, nombre, apellidos y fecha de nacimiento que para lo que vamos a hacer nos vale.

Ahora crearemos nuestro modelo proxy que extenderá del modelo contactos, para ello en el mismo archivo añadimos el siguiente código:

class ExtensionContacto(Contacto):
    class Meta:
        proxy = True

A parte de no calentarme mucho la cabeza con el nombre de la clase, lo que hacemos es extender de la clase Contacto y dentro de ella, en la clase Meta, damos el valor True a la variable proxy que indicará que es una clase de este tipo y no necesitará que cree una tabla para este modelo.

Ahora que tenemos todo listo añadiremos funcionalidades extra como que al hacer traer todos los usuarios el orden sea por los apellidos, una función para obtener la edad del contacto y otra que nos muestre el nombre y apellidos del contacto.

Para modificar el orden simplemente tenemos que añadir dentro de Meta ordering = ["apellidos"] para ordenar por apellidos.

class ExtensionContacto(Contacto):
    class Meta:
        proxy = True
        ordering = ["apellidos"]

Si traemos todos los objectos al recorrerlos nos aparecerán ordenados por el apellido:

c = ExtensionContacto.objects.all()

for contact in c:
    print(contact.nombre + ' ' + contact.apellidos)

Ahora añadiremos las funciones para obtener el nombre, apellidos y la edad, para ello añadimos las dos funciones en nuestro modelo proxy que se llamarán get_edad y get_datos_contacto. Ahora nuestro modelo quedaría así:

from django.db import models
import datetime

class Contacto(models.Model):
    nombre = models.CharField(max_length=50)
    apellidos = models.CharField(max_length=100)
    fecha_nacimiento = models.DateField()

class ExtensionContacto(Contacto):
    class Meta:
        proxy = True
        ordering = ["apellidos"]


    def get_datos_contacto(self):
        # print('El contacto se llama {} y sus apellidos son {}'.format(self.nombre, self.apellidos))
        return self.nombre + ' ' + self.apellidos


    def get_edad(self):
        today = datetime.date.today()
        y = self.fecha_nacimiento.year
        m = self.fecha_nacimiento.month
        d = self.fecha_nacimiento.day
 
        edad = today.year - y

        if(m > today.month):
            edad = edad - 1
        elif(m == today.month and d > today.day):
            edad = edad - 1

        # print('La edad del contacto {} es {}'.format(self.nombre, edad))
        return edad

Y para usarlas por ejemplo podemos traernos todos los usuarios y luego al recorrer los contactos las llamamos:

c = ExtensionContacto.objects.all()

for contact in c:
    contact.get_edad()
    contact.get_datos_contacto()

Como veis Django nos ofrece algunas formas sencillas de extender la funcionalidad de nuestros modelos, os animo a que lo uséis y recordad que cualquier duda podéis ponerla en la caja de comentarios que estaré encantado de ayudaros :), también podéis clonar el proyecto que he utilizado para este ejemplo desde mi github.

1009 vistas

Nos tomamos en serio tu privacidad

Utilizamos cookies propias y de terceros para mejorar la experiencia del usuario a través de su navegación. Si pulsas entendido aceptas su uso. Ver política de cookies.

🐍 Sígueme en Twitter

Si te gusta el contenido que subo y no quieres perderte nada, sígueme en Twitter y te avisaré cada vez que cree contenido nuevo 💪
Luego ¡Te sigo!