Está en la página 1de 3

🔓

Contenttypes Framework
Django incluye la aplicación contenttypes que rastrea todos los modelos instalados en
nuestro proyecto, proporcionando una interfaz genérica de alto nivel para trabajar con
ellos.
En el núcleo de la aplicación reside el modelo ContentType que se encuentra dentro del
módulo django.contrib.contenttypes.models . Las instancias de esta clase representan y
almacenan información sobre los distintos modelos instalados en el proyecto. De esta
manera, cada vez que se instalan nuevos modelos, se crean automáticamente nuevas
instancias de ContentType .
Las instancias de ContentType tienen métodos para devolver las clases de modelo que
representan y para consultar objetos de dichos modelos.

🍀 Instalar el framework contenttypes


El framework está incluido en la lista predeterminada de INSTALLED_APPS . Si lo eliminó o
si configuró manualmente la lista de aplicaciones, puede habilitarlo añadiendo el
módulo django.contrib.contenttypes a la variable de configuración.
Es recomendable tener instalado el framework de tipos de contenido, ya que varias de
las otras aplicaciones predefinidas lo utilizan:

La aplicación de administración lo usa para registrar el historial de cada objeto


agregado o modificado a través de la interfaz de administración.

El framework de autenticación lo usa para vincular los permisos de usuario con


modelos específicos.

🍀 El modelo ContentType
Contenttypes Framework 1
Cada instancia de ContentType tiene dos campos que, en conjunto, describen de forma
única un modelo instalado: app_label que indica el nombre de la aplicación a la que
pertenece el modelo, y model que indica el nombre de la clase.

🍀 Métodos de instancias de ContentType


.get_object_for_this_type(**kwargs)

Toma un conjunto de argumentos de búsqueda válidos para el modelo que


representa ContentType y realiza una búsqueda .get() en ese modelo, devolviendo
el objeto correspondiente.
.model_class()

Devuelve la clase de modelo representada por esta instancia de ContentType .


ContentType.objects.get_for_id(id)

Busca un ContentType por ID.


ContentType.objects.get_for_model(model)

Toma una clase de modelo o una instancia de un modelo y devuelve la instancia de


ContentType que representa ese modelo.

from django.contrib.contenttypes.models import ContentType

user_type = ContentType.objects.get(app_label='auth', model='user')


user_type.model_class() # <class 'django.contrib.auth.models.User'>
user_type.get_object_for_this_type(username='Guido') # <user: Guido>

🍀 Relaciones genéricas
Agregar una clave foránea de uno de sus propios modelos a ContentType permite que el
modelo se vincule efectivamente a otra clase de modelo. Pero es posible ir un paso
más allá y usar el tipo de contenido para habilitar relaciones verdaderamente genéricas
entre modelos.

from django.contrib.contenttypes.fields import GenericForeignKey


from django.contrib.contenttypes.models import ContentType
from django.db import models

class TaggedItem(models.Model):
tag = models.SlugField()

content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)


object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')

def __str__(self):
return self.tag

Una clave foránea normal solo puede referenciar otro modelo, lo que significa que si el
modelo TaggedItem usa una clave foránea, tendría que elegir uno y solo un modelo para
almacenar las etiquetas. La aplicación contenttypes proporciona un tipo de campo

Contenttypes Framework 2
especial GenericForeignKey que soluciona esto y permite que la relación sea con
cualquier modelo:

Esto habilitará una API similar a la utilizada para una clave foránea normal, cada
TaggedItem tendrá un campo content_object que devuelve el objeto con el que está

relacionado, y también puede asignarlo a ese campo o usarlo al crear un TaggedItem .

from django.contrib.auth.models import User

guido = User.objects.get(username='Guido')

t = TaggedItem(content_object=guido, tag='bdfl')
t.save()
t.content_object # <User: Guido>

guido.delete()
t.content_object # None

Contenttypes Framework 3

También podría gustarte