Hello BackEnders
Today, I decided to explain OneToOne , ManyToMany , and Foreignkey in Django
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.
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".
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:
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.
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:
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 🎂
Top comments (2)
Hello Manar Abdelkarim,
thank you for your article.
I enjoyed reading it despite having no experience with Django.
In my opinion it is easy to understand and sometimes even funny, e.g. the explanation of the chair with the .gif.
I smiled a bit :D!
By the way I found some minor typos(see "Represent Foreignkey in Django:"):
repationship from the many sides..
Tom ..
"record" ..
Should be(unless you had some other intentions):
relationship from the many sides.
Tom.
"record".
Very Well described. Happy Birthday and good luck to you.