What is Django ContentType
Tags: django, python
Published: 2021-08-23 05:31:34

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/