Django: Many to Many Relationship in 5 steps

A many-to-many relationship refers to a relationship between tables in a database when a parent row in one table contains several child rows in the second table, and vice versa. Many-to-many relationships are often tricky to represent.

The many-to-many relationship is usually a mirror of the real-life relationship between the objects the two tables represent.

Let’s imagine that we work with a company that teaches courses. This company has a website where they publish the courses that will be taught in the month. The problem is that when a person wants to attend a course, he has to go to the company to enroll in the course. What they are looking for is to implement a system that allows users to register to the courses they want from the website.

This is a clear example of a many to many relationship. A user must be able to enroll in many courses, and a course must be able to have many users registered. But how are we going to achieve that? Let’s begin!

Step 1:

First you have to declare a class, in this case I’m going to name it “User” because in this example the relationship that we will create is between users and courses, a User is going to enroll to different Courses, and a Course is going to have several users registered.

Then you have to declare the class that is going to be related to “User”, in this example is “Course”. Don’t forget to import User from the file that it belongs to, in case it is in a different one.

As you can see at the bottom of the class we have an attribute called “users” and the Field Type is a ManyToManyField. The parameter that it receives is the name of the “User” class, and because we want users to register to the course by themselves and not assigned them since the beginning, we are going to set blank=True.

Now we must migrate both models in order to have them sync with our database, and for that purpose we are going to run in the command prompt, in the folder we are working on, the following commands.

Step 2:

Now we have to define two class methods, “subscribe” and “unsubscribe”. The parameters that they receive are the same, “cls” because it’s a classmethod, “current_user”, “new course” or “cancel_course” depending on the method.

For “subscribe” method we are going to link the user to the course, and the way we will achieve that is with the following line: new_course.users.add(current_user), this mean that from the course received as a function parameter, you are going to add the actual user.

For “unsubscribe” we are basically doing the same thing: cancel_course.users.remove(current_user), this mean that from the course received as a function parameter, you are going to remove the actual user.

Step 3:

Let’s start with, in this file we are going to import “Course” and “User” from their file, and we will define this function.

In this function we are receiving three parameters, “request”, “indicacion”(instruction), and “pk”. Then we will get the specific course that we will relate to the user with this line: curso = Curso.objects.get(pk=pk).

Depending on the “indicacion”(instruction), this function will call the “inscribir” or “cancelar_inscripcion” defined in the model. Sounds good right? But where are we getting the “indicacion” parameter from? That takes us to the next step.

Step 4:

Now we must add a path to the urls, where the “pk” and “instruction” parameter are going to be sent.

In the path as you can see there is <instruction>/<pk> which means that you are going to get two values for those positions, then we are going to send it to views.change_course, that is the name of the view function, and also we assign a name to the path, in this case is ‘change-course’. We will use that in the HTML file.

Step 5:

This is the last part, as you can see in this html file, in order to add python code to html you just have to write it between this characters“{% %}”. In the first line we are making sure that a user is authenticated, then we verify if the user is already register in a course he or she will see a button that says “Unsubscribe” and the url will receive the “instruction” and “pk”. Otherwise another button will appear but this will say “Subscribe” and send the corresponding values to the url.

Congratulations, you have successfully applied a many to many relationship to your project!!