In this series, we will understand Django's ContentType and what is GenericForeignKey with examples. contenttypes
is a Django app that can track all of the models installed in our Django-powered project, providing a high-level, generic interface for working with our models.
If we check in settings INSTALLED_APPS
we can see, that django.contrib.contenttypes
is readily present.
INSTALLED_APPS = [
...
'django.contrib.contenttypes',
...
]
Since contenttypes
is just like any other app, it also has migrations and, and views.py. The most important model of the contenttypes app is ContentType
. Let's see what fields ContentType has.
class ContentType(models.Model):
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
class Meta:
verbose_name = _('content type')
verbose_name_plural = _('content types')
db_table = 'django_content_type'
unique_together = [['app_label', 'model']]
def __str__(self):
return self.app_labeled_name
Apart from the custom manager, it has app_label
and model
both as string fields, which also are unique_together
.
- app_label is the name of the application the model is part of.
- model is the name of the model itself.
We have already established that ContentType
is a model that tracks all the models in your Django app and therefore, as soon as we create a new table in the database, a new entry gets created for the new table in the ContentType table. Consequently, ContentType
model objects "points" to a particular table in your Django app. Let's see few entries in the ContentType table.
>>> from django.contrib.contenttypes.models import ContentType
>>> ContentType.objects.filter(model='user').values()
<QuerySet [{'id': 4, 'app_label': 'auth', 'model': 'user'}]>
>>> ContentType.objects.filter(model='contenttype').values()
<QuerySet [{'id': 5, 'app_label': 'contenttypes', 'model': 'contenttype'}]>
Since ContentType
itself is a model, the ContentType model also tracks itself and thus has an entry for itself, this sounds a bit confusing but makes complete sense.
ContentType model has 2 important methods, model_class
and get_object_for_this_type
, let's see with an example what these methods do.
>>> from django.contrib.contenttypes.models import ContentType
>>> user_ct = ContentType.objects.get(model='user')
>>> user_ct.model_class()
django.contrib.auth.models.User
>>> user_ct.get_object_for_this_type(username='bob')
<User: bob>
Okay, so now at this point we know what ContentType is, but what good is it for? Why do we need this?
- GenericForeignKeys are implemented via ContentType, we will see this in the next part of this article about how ContentTypes are used.
- The admin application uses it to log the history of each object added or changed through the admin interface. Django’s authentication framework uses it to tie user permissions to specific models.
- Since we have all models listed here in one place, we can use this to build generic solutions.
In this article, we understood about ContentType
model and contenttypes
framework, in the next article, we will see one of the implementations of ContentType
which is GenericForeignKey
.
To read more, please visit: https://buildatscale.tech/what-is-django-contenttype/
Top comments (0)