¿Qué es la herencia de modelos en Django?
La herencia le permite reutilizar código y crear modelos de datos más limpios. Pero Django ofrece más de una forma de heredar, así que asegúrese de conocer las diferencias.
La herencia de modelos es una característica de Django ORM que permite a los desarrolladores crear relaciones jerárquicas entre modelos de bases de datos. Permite la reutilización y extensibilidad del código y una base de código más limpia aprovechando los principios de la programación orientada a objetos.
Ya sea que esté creando una aplicación web compleja o trabajando en un proyecto más pequeño, la herencia de modelos puede ofrecer beneficios significativos, como reducir la redundancia y garantizar un comportamiento consistente.
Tipos de herencia de modelos en Django
Django ofrece soporte para tres tipos de herencia de modelos:
- Clases base abstractas.
- Herencia de varias tablas.
- Modelos proxy.
Cada uno de estos tipos de herencia de modelos tiene beneficios y los utilizará para propósitos específicos.
Clases base abstractas
Las clases base abstractas proporcionan una forma de definir campos y métodos comunes que pueden heredar varios modelos. Por ejemplo, si tiene dos modelos que comparten campos similares, puede utilizar una clase base abstracta para definir campos similares. Echale un vistazo a éste ejemplo:
class Customer(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
customer_id = models.IntegerField()
class Seller(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
seller_id = models.IntegerField()
El fragmento de código anterior define dos modelos de Django: Cliente y Vendedor. Estos modelos comparten dos campos comunes, a saber, nombre y correo electrónico. Para evitar esta redundancia, puede crear un modelo separado para contener los campos comunes en los modelos Cliente y Vendedor y hacerlo abstracto.
class UserInfo(models.Model):
name = models.CharField(max_length=50)
email = models.EmailField()
class Meta:
abstract = True
El fragmento de código anterior define un nuevo modelo y establece el atributo abstracto en Verdadero. Esto significa que el modelo será abstracto y Django no creará una tabla en la base de datos.
Puedes reescribir los modelos Cliente y Vendedor de esta manera:
class Customer(UserInfo):
customer_id = models.IntegerField()
class Seller(UserInfo):
seller_id = models.IntegerField()
En el fragmento de código anterior, los modelos Cliente y Vendedores heredan del modelo UserInfo en lugar de models.Model.
Puedes ver tus modelos en el panel de administración registrándolos en tu archivo admin.py de esta manera:
from .models import Customer, Seller
admin.site.register(Customer)
admin.site.register(Seller)
Migre sus modos e inicie su servidor de desarrollo ejecutando lo siguiente en una línea de comando:
python manage.py makemigrations \
&& python manage.py migrate \
&& python manage.py runserver
Navegue a su sitio de administración e inicie sesión con sus datos de superusuario. Deberías ver los tres campos para cada modelo.
En este ejemplo, Django ha creado una tabla para los modelos Cliente y Vendedor. Puedes ver que el modelo UserInfo no tiene tabla ya que es abstracto.
Herencia de varias tablas
Puede utilizar la herencia de tablas múltiples cuando el modelo principal también debe existir como una tabla en la base de datos junto con el modelo secundario.
A diferencia de la herencia de clases base abstracta, donde el modelo principal no será una tabla en la base de datos, la herencia de tablas múltiples crea una tabla para el modelo principal.
En la herencia de tablas múltiples, el modelo hijo hereda todos los campos y métodos de su modelo padre y agrega sus campos específicos. Las claves externas ayudan a establecer la relación de modelo entre los modelos padre e hijo.
A continuación se muestra un ejemplo de herencia de tablas múltiples:
class Person(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
def get_name(self):
return f"{self.first_name} {self.last_name}"
class Meta:
abstract = True
class Employee(Person):
employee_id = models.CharField(max_length=20)
department = models.CharField(max_length=100)
salary = models.FloatField()
dob = models.DateField()
class Manager(Employee):
title = models.CharField(max_length=100)
Este fragmento de código define tres modelos. El primer modelo, llamado Persona, es abstracto. Define solo el nombre y apellido de una persona.
El segundo modelo, llamado Empleado, hereda los campos de Persona pero define campos adicionales. El modelo Employee no es abstracto, por lo que tendrá su tabla en la base de datos.
El modelo final, llamado Administrador, hereda los campos del modelo Empleado y agrega un campo llamado título.
La relación entre los modelos Empleado y Administrador se denomina Herencia de múltiples tablas. Migra tus modelos, regístralos en admin.py, inicia tu servidor y navega hasta el panel de administración. Deberías ver dos tablas creadas por Django.
Cuando intente agregar un nuevo administrador, notará que tiene todos los campos del modelo Empleado, así como su propio campo personalizado.
Modelos proxy
Un modelo proxy le ayuda a crear un nuevo modelo que se extiende a partir de un modelo existente sin crear una nueva tabla de base de datos. En este tipo de herencia de modelos, los modelos proxy y original compartirán la misma tabla. Al utilizar modelos proxy, puede hacer cosas como crear modelos personalizados y cambiar los administradores predeterminados.
Puede crear un modelo de proxy agregando proxy=True en la clase Meta. He aquí un ejemplo:
class ProxyModel(BaseModel):
class Meta:
proxy = True
El uso típico de un modelo proxy es apropiado cuando existe un modelo base y es necesario crear una versión especializada del mismo con funcionalidad adicional. Aquí hay un ejemplo básico:
class Post(models.Model):
title = models.CharField(max_length=30)
author = models.CharField(max_length=30)
def __str__(self):
return self.title
class ProxyPost(Post):
class Meta:
proxy = True
Este fragmento de código define dos modelos: Publicar y MiPost. El modelo Publicación define dos campos para título y autor. El modelo ProxyPost hereda del modelo Post.
Migre los modelos anteriores y agregue una nueva publicación a la tabla creada para el modelo Publicar.
Después de agregar la publicación, abra la tabla Publicaciones proxy. Deberías encontrar la publicación que agregaste a la tabla Publicaciones en ella.
Los cambios que realice en las publicaciones en la tabla Publicaciones proxy afectarán a la publicación correspondiente en la tabla Publicaciones y viceversa. Esto demuestra que realmente comparten la misma mesa.
Puede modificar el método str() del modelo proxy:
class ProxyPost(Post):
class Meta:
proxy = True
ordering = ["title"]
def __str__(self):
return self.author
Con esta modificación, la representación de cadena de un ProxyPost será su autor, no el título. El orden del modelo de proxy también será por título en lugar del campo de ID predeterminado.
Al utilizar modelos proxy, debe tener en cuenta que no puede agregar campos personalizados a su modelo proxy. El caso de uso principal de los modelos proxy es cuando desea que un modelo admita múltiples comportamientos.
Los modelos proxy le ayudan a cambiar el comportamiento de un modelo existente sin modificar sus campos o la estructura de la tabla de la base de datos subyacente.
Utilice la herencia de modelos para la reutilización del código y la estructura organizativa
Al utilizar las diferentes técnicas de herencia de modelos, puede crear fácilmente código organizado y reutilizable para su proyecto.
La herencia de modelos evita el código redundante y mejora la capacidad de mantenimiento y escalabilidad de su código. También facilita la navegación por el código, fomentando así la colaboración eficiente entre los equipos de desarrollo.
Además de la herencia de modelos, Django ofrece herencia de plantillas, que es una excelente manera de administrar y organizar plantillas para sus proyectos.