Models' Relationship In Django
Tags: django, python, database, tutorial
Published: 2021-09-25 23:26:16

Hello BackEnders 

Today, I decided to explain OneToOne , ManyToMany , and Foreignkey in Django 

![Django model](https://media.giphy.com/media/eXTue7sCt6ZvG/giphy.gif)
So let's get started:

## Why do we use relationships?

The first step to understand the relationships is to understand why we need them. Let's not talk too much about the concept of "Normalization", imagine if we have a table with students names, gender, and school events :



| StudentID  | StudentName |  StudentGender | StudentsClass | StudentDesk| SchoolEvents |
| :--- | :---        |    :----:   |          ---: |  ---:|---:|
| 1       |    Natchos  |        Male | 4A | 321 |Zoo Visit, Charity Day |
| 2       | Manar       | Female| 5A |40 |Charity Day|
| 3       | Kareem        | Male     | 4A |66 | Zoo Visits , Math Competition |

you can notice here that every student has a desk "represented with a number" but why do we have this data in this table? Also, "Male" in StudentGender and "4A" in StudentsClass has been repeated twice in the table. And the worst is in the SchoolEvents column. Just think if we want to delete the Zoo Visit from Natchos's ongoing events, the Charity Day will be deleted too! 
Imagine if we have 100 or 1000 students!

Instead, we have to divide the table into smaller tables "four tables in our case" 

| StudentID  | StudentName 
| :---        |    :----:  |
| 1       |    Natchos  |
| 2       | Manar       |
| 3       | Kareem       | 


| ID  |  StudentGender |
| :--- |          ---: |
| 1   |        Male |
| 2 | Female|

| ID  | StudentsClass 
| :---        |    :----:  |
| 1       |    4A |
| 2       | 5A   |


| ID  | Events 
| :---        |    :----:  |
| 1       |    Zoo Visit|
| 2       | Charity Day   |
| 3       | Math Competition | 


Perfect. But what is next? We need a way "a link" to tell the database that this particular student is in this class, has this gender and will go to these events.
That is what we do with relationships. A relationship is an association between two entities.

## Foreignkey:

I started with Foreignkey because it is the easiest to understand. 

Foreignkey in Django represents **"one to many"** also called **"many to one"** relationship in the database. 
it is just the same as its name one to many! I have one mother and my mother has many children. The country has many cities and every city is located in one country.
In our example above, every student "normally" should have one gender. and every gender is for many students. 
Natchos and Kareem are two students "many", Male is one.

![One To many](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wohg10xd98uksfvc1lq2.jpg)

###  Represent Foreignkey in Django:

Because we can not represent all the "many" in the "one" table. It makes a lot of sense to represent the repationship from the many sides.. which means in our example we can't go to the Gender table add a row and say in it: we have a relationship with Natchos , and Kareem and John and Tom ..etc in the male row "record" .. instead we can add a row in the student row and called gender that says these students a relationship with the Gender table in "Male" or in "Female".

![many to one](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on0jm6pfa6fbilmczp8v.jpg)

Now to represent the ForeignKey will add it in the Student Field with one main parameter: referring to the model that has ForeignKey relationship "many to one" with it.

    from django.db import models

    class StudentGender(models.Model):
        gender = models.CharField(max_length=10)
    class Student(models.Model):
        name = models.CharField(max_length=30)
        gender = models.ForeignKey(StudentGender, 
       null=True)
    
Notice in class Student :

    gender = models.ForeignKey(Gender, 
       on_delete=models.CASCADE)


That in Django we don't refer to the id of the other model but for the model "class" itself ( in other frameworks such as Flask, we refer to the other model's id). Also, we used null=True to allow the nulls so we can have some students with no gender specified.

## OneToOne

one to one is as easy as you can think. this pen is mine and this pen has one owner. I have one husband and my husband has one wife. In our example, every student setting on one desk and every desk is for one student "at least in my country" 

###  Represent OneToOne in Django:

![one to one](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vpiz7dffrltbgtu81yu2.jpg)


At this point and because we are going to add one value in either table, it doesn't matter where we add it. But because I think that it is a good idea to add in the Chair table since that the student is the main character, I will add the OneToOne field to the Chair :

    class StudentGender(models.Model):
        gender = models.CharField(max_length=10)
        Student = models.OneToOneField(Student, 
       null=True)
    class Student(models.Model):
        name = models.CharField(max_length=30)
        gender = models.ForeignKey(StudentGender, 
       null=True)
    
    Notice in class Student :

    gender = models.ForeignKey(StudentGender, 
       null=True)

Notice that here I also used "null=True" because as you know, if a chair has no student to set on, we don't have to throw it from the window. 

![one to one](https://thumbs.gfycat.com/ScalySelfassuredDuck-max-1mb.gif)


#ManyToMany

Students enroll in many courses and every course is enrolled by many students. in our example, each student can attend many events and every event will be attended by many students. This is simply what a many to many relationships is. 


###  Represent ManyToMany in Django:

In ForeignKey we chose the "one" table and in OneToOne we chose either one. so what table can we choose in many to many? In the normal cases, we create a third table "more like a third wheel in the relationship" that has the id of the first table and the id of the second table as below:

![many to many](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iye7rnmay7m5jebnlnz7.jpg)

#### But!
### But!
## But!

Django made it easier for us. it is just as easy as adding ManyToOne or foreignKey!Again I will not choose the student.

    class Student(models.Model):
        name = models.CharField(max_length=30)
        gender = models.ForeignKey(StudentGender, 
       null=True)

    class Chair(models.Model):

    chair_number = models.IntegerField()
    student = models.ManyToManyField('student')


Here, It seems we have reached the end. 
Happy day to you and happy birthday to ME 🎂


## References:
- [Django Models with Relationships — One to One Relationship](https://sjlouji10.medium.com/django-models-with-relationships-one-to-one-relationship-f3ef8d77aec1)
- [Model field reference¶
](https://docs.djangoproject.com/en/3.2/ref/models/fields/)