Django Generic Relationship

Learn via video courses
Topics Covered

Overview

Django includes a content type application that tracks all of the models installed in our project, allowing us to work with your models in a high-level, generic interface. One of the ContentTypes' use cases is to create generic relationships between models. Generic Relations are a type of relation supported by Django in which the relationship (foreign key) is not bound to a specific table rather it allows us to create a one-to-many relationship with any target model. This can be useful if we want to implement a comment system or a like system that allows us to leave comments or likes on posts, images, and comments themselves.

Introduction

Relation or relationship is any association between two entity types. A relationship exists between two relational database tables in which one table has the foreign key of the primary key of the other table. To clearly understand the above statement let us consider an example, say we store an engineering student's details with their department name and ID. Now the department from which the student belongs might be electrical, mechanical, IT, or machine learning. The model for the above case is as follows

But the inadequacy in this model is that if we want to delete the electrical department, we will have to go to the student table and alter every single student's detail manually. Therefore, a relationship among them is created to avoid the hassle of altering every single detail. Two entities are created, the model department and the model student.

A relationship among both entities is created by keeping thedep_idas a foreign key in the model student and also a primary key in the department model. This ensures that any modification in the department table is reflected in the student table.

There are three types of relations in the Django model:

  • One-to-one relationships
  • Many-to-many relationships
  • Many-to-one relationships introduction to Generic Relationship

One-to-One relationships

In this type of relationship, one record of a particular model is related to exactly one record of another model. This relation is defined byOneToOneField. Let us take an example, suppose we have a Student model and a UID model.

So a student can only have reg_no and roll_no, whereas a particular reg_no and roll_no can belong to a particular student only. In the above code,

  • We created a model UID and model Student.
  • In the model Student, we link the model UID in the field UID by using models.OneToOneField(UID, on_delete = models.CASCADE, primary_key = True).
  • on_delete = models.CASCADE ensures that all the related records (reg_no, roll_no) in the linked model UID are also deleted when the record in the model Student is deleted.

Many-to-Many relationships

Each record of the first model is related to many records of the second model, and each record of the second model is also related to many records of the first model. This relation is defined byManyToManyField. Let us take an example, suppose we have a Customer model and a Product model.

So a product can have multiple customers whereas a customer can have multiple products. In the above code,

  • We created a model Product and a model Customer.
  • We linked the model Product and the model Customer using a fieldprodbymodels.ManyToManyField(Product).

Many-to-One relationships

In this type of relationship, one record of the first model is related to multiple records of the second model but one record of the second model is related to only one record of the first model. This relation is defined byForeignKey. Let us take an example, suppose we have a Song model and an Album model.

Therefore, a particular album can have multiple songs but a song can have only one album only. In the above code,

  • We created models Album and Song.
  • We linked both models using the field album in the model Song.

Content Types in Django

ContentType instances represent and store information about the models in our project, and new instances of ContentType are created automatically whenever new models are installed. As a result, ContentType model objects point to a specific table in our Django app. Because we have a Database representation of tables in these Content Type tables, Django uses this to refer to a table and then adds an integer field to link to an id of that specific table, completing a relationship because we now have the table and its id. To use the content type module we first need to mentiondjango.contrib.contenttypes in thesettings.py file under INSTALLED_APPS.

Generic Relationship in Django

A Django generic relationship is a type of relationship that allows you to create a one-to-many relationship with any target model. Say we have a social media application in which we can like a post, comment, or page. So we create a model using a content type module and use it as a generic relation with the models' post, comment, or page. The generic relationship allows us to connect to a single model like with multiple models such as post, comment, or page.

Code Examples of Generic Relationships

So let us consider an example. Say we want to create a project in which we can comment on the books. We create a project name wick and applications named rec_com and record. We first activate a virtual environment before creating the project and applications.

Now we register the applications in thesettings.pyfile under INSTALLED_APPS section. This section contains the list of the applications we created and also the preinstalled applications like django.contrib.contenttypes,django.contrib.admin, etc.

After doing this, we are supposed to make the models in both applications. Therefore in the application rec_com we make model Comment, which would help us post comments on any of the books in our database.

Since we are working with ContentType and GenericForeignKey we are supposed to import the same. Therefore, in the above code

  • We create a model Comment.
  • The following fields are the mandatory fields for a generic relation: content_type, object_id, and content_object.
  • The content_type is a reference to the relation's content type or table.
  • The object_id is used to store the row's id.
  • The content_object is a direct reference to the object that the comment entry is associated with.
  • The field text is used to enter the comment.

Now we register the app in theadmin.py file.

We make a model Author and Book in the application record. In this step we connected the model Comment (which would help us comment on the records of the model Book) to the model Book.

In the above code,

  • We imported the model comment from the rec_com application.
  • We imported Generic relations to use in our model.
  • We made two models Author and Book.
  • In the model Book, we created a field author to link the model Author.
  • We created a field com and connected the model Comment from app rec_com using Generic Relation. We again register the above models in the admin.py file,

Now we make migrations in the command prompt using the following,

Now we activate the shell.

In the shell, we import the models and then enter records and the comment.

Therefore, this is the way we can add comments to the books.

Fields Required for Generic Relationships

  • Foreign key: Adding a foreign key from one of your models to ContentType in Generic relations allows your model to effectively tie itself to another model class. It is used to conneect a particular field to a model.
  • Primary key of related object: The primary key is a collection of attributes (or attributes) that uniquely identify the tuples in relation or table.

Reverse Relation in Generic Relationships

Considering the example in the above section, we made a query and added a comment based on the name of the Author. In reverse relation, we are making a query based on the number of comments the Author got on her book. In the output variable, book we stored all the records then based on the Author's name we made a query for the book in the field com, since we want the name of the author in the queryset.

Disadvantages of Generic Relationship

  • GenericForeignKey does not accept the on_delete argument. All relations will be cascaded by default, that is if one data is deleted all relations will be disappeared.
  • The disadvantage of using generic relations is that complex queries are more difficult to code and run slower.

Conclusion

Hello developer!! I am sure by now you must have learned what Django generic relationship is. Let us summarize what we have learned so far

  • Django Generic Relations are a type of relation supported by Django in which the relationship (foreign key) is not bound to a specific table rather it allows us to create a one-to-many relationship with any target model.
  • A relationship exists between two relational database tables in which one table has the foreign key of the primary key of the other table.
  • There are three types of relationships in the Django model: One-to-one relationships, Many-to-one relationships, and Many-to-many relationships.
  • The Content Type module allows you to perform a variety of operations and manipulations on a model.