Django Querysets | Backward, Reverse and ManyToMany Relationships
Table Of Contents
- Select Objects Using Backward/Reverse Relationships
- Get Student List of who is enrolled to a specific Course through Backward Relationship
- Get list all student enrolled to any course using Backward Relationship
- ManyToMany Relationship
- Filtering Querysets from ManyToMany
- Conclusion
Select Objects Using Backward/Reverse Relationships
Below query is an example of a reverse relationship where we have Course
objects which have ForeignKey
relationship with Subject
Model.
If you have already gone through our post on Django Quersets | One To One Foreign Key, Inner Joins, Query Filtering then you have learnt to retrive course subjects from Subject Model.
>>> bca_course = Course.objects.get(pk=1) >>> print(bca_course) BCA >>> #Now we will get All Subjects of BCA Course Through Backward Relationship >>> bca_subjects = bca_course.subject_course.all() >>> print(bca_subjects) <QuerySet [<Subject: C Programming>, <Subject: DataStructures using C>, <Subject: Visual Programming>]>
bca_course.subject_course
returns all the subjects related to a course.This is a great advantage over other frameworks where you have to manually specify reverse/backward relationships.
>>> bba_course = Course.objects.get(pk=3) >>> print(bba_course) BBA >>> bba_subjects=bba_course.subject_course.all() >>> print(bba_subjects) <QuerySet [<Subject: Business Administration>, <Subject: Economics>, <Subject: Accounting>, <Subject: Introduction to Taxation>, <Subject: Business Marketing>]>
Get Student List of who is enrolled to a specific Course through Backward Relationship
>>> bca_course = Course.objects.get(pk=1) >>> print(bca_course) BCA >>> student_list = bca_course.course.all() >>> print(student_list) <QuerySet [<Student: Suresh>, <Student: Kiran>, <Student: Vasudev>]>
The bca_course.course
gets a list of students from Student Model who enrolled to course BCA.
Accessing other model information through student object.
>>># Access field values by index >>> student_list[1] <Student: Kiran> >>> student_list[1].name 'Kiran' >>> student_list[1].joining_date datetime.date(2018, 2, 5) >>> student_list[1].course.course_name 'BCA' >>> student_list[1].course.id 1 >>> student_list[1].course.course_desc 'BCA fullform (Bachelor of Computer Application) is a 3 year course which provides basic knowledge of computer programming and application'
Get list all student enrolled to any course using Backward Relationship
>>>course_list = Course.objects.all() >>>student_list = [] >>>for course in course_list: [student_list.append(student) for student in course.course.filter()] >>> print(student_list) [<Student: Suresh>, <Student: Kiran>, <Student: Vasudev>, <Student: Rakshit>, <Student: Amar>, <Student: Prakash>, <Student: Naresh>]
Here we get all courses and loop over and get student belonging to that particular course.
ManyToMany Relationship
Let us create another model ExamMarks which has a ManyToMany relationship with Student and Subject Model.
In models.py.
class ExamMarks(models.Model): id = models.AutoField(primary_key=True) student = models.ManyToManyField(Student,related_name="exam_marks_student") subject=models.ManyToManyField(Subject,related_name="exam_marks_subject") obtained_marks = models.FloatField(max_length=12) class Meta: db_table="subject_marks" verbose_name="Subject Marks" def __str__(self): return str(self.obtained_marks)
After migrating this model we get 3 tables in MySQL they are subject_marks
which has id
and obtained_marks
field.
subject_marks_student
table which has id
,exammarks_id
and student_id
as ForeignKey.
subject_marks_subject
table which has id
, exammarks_id
and subject_id
as ForeignKey.
Populating ExamMarks Models
Adding marks scored by students. We will intentionally exclude a few students as they did not attend the exam.
>>> from query_sets.models import Course, Subject, Student, ExamMarks >>> >>> bba_course = Course.objects.get(pk=1) >>> bca_course = Course.objects.get(pk=3) >>> >>> bba_ecomonics = Subject.objects.get(pk=5) >>> student_1 = Student.objects.get(pk=2) >>> >>> exam_marks_1 = ExamMarks(obtained_marks=74.5) >>> exam_marks_1.save() >>> >>> exam_marks_1.student.add(student_1) >>> exam_marks_1.save() >>> exam_marks_1.subject.add(bba_ecomonics) >>> exam_marks_1.save() >>> >>> bba_business_marketing = Subject.objects.get(pk=8) >>> exam_marks_2 = ExamMarks(obtained_marks=55) >>> exam_marks_2.student.add(student_1) >>> exam_marks_2 = ExamMarks(obtained_marks=55) >>> exam_marks_2.save() >>> exam_marks_2.student.add(student_1) >>> exam_marks_2.save() >>> exam_marks_2.subject.add(bba_business_marketing) >>> exam_marks_2.save() >>> bca_visual_prog = Subject.objects.get(pk=3) >>> student_2=Student.objects.get(pk=5) >>> exam_marks_3=ExamMarks(obtained_marks=65.00) >>> exam_marks_3.save() >>> exam_marks_3.student.add(student_2) >>> exam_marks_3.save() >>> exam_marks_3.subject.add(bca_visual_prog) >>> exam_marks_3.save() >>> >>> bba_taxation = Subject.objects.get(pk=7) >>> student_3=Student.objects.get(pk=1) >>> exam_marks_4=ExamMarks(obtained_marks=59.5) >>> exam_marks_4.save() >>> exam_marks_4.student.add(student_3) >>> exam_marks_4.subject.add(bba_taxation) >>> exam_marks_4.save()
Filtering Querysets from ManyToMany
Get Marks Secured by a student and other student details
>>> from query_sets.models import Course, Subject, Student, ExamMarks >>> student = Student.objects.get(pk=5) >>> print(student) Vasudev >>> subject_attended_on_exam = ExamMarks.objects.filter(student=student) >>> print(subject_attended_on_exam) <QuerySet [<ExamMarks: 65.0>]> >>> #Get Student other details >>> student_object = subject_attended_on_exam[0].student.get() >>> print(student_object) Vasudev >>> print(student_object.course.course_name) BCA >>> print(student_object.course.subject_course.filter()) <QuerySet [<Subject: C Programming>, <Subject: DataStructures using C>, <Subject: Visual Programming>]>
First, we select a student object from the model Student
and filter in ExamMarks model this gets use list of matched objects.
Through subject_attended_on_exam
objects we can get student information as well by subject_attended_on_exam[0].student.get()
.
Get a list of subjects with marks by student course
>>>from query_sets.models import Course, Subject, Student, ExamMarks >>>student_list = Student.objects.all() >>>for student in student_list: student.subjects = student.course.subject_course.filter() for subject in student.subjects: try: subject.marks_scored = ExamMarks.objects.get(student=student,subject=subject) except: subject.marks_scored=[] >>> print(student_list) <QuerySet [<Student: Rakshit>, <Student: Amar>, <Student: Suresh>, <Student: Kiran>, <Student: Vasudev>, <Student: Prakash>, <Student: Naresh>]> >>>print(student_list[1].subjects[1]) Economics >>>print(student_list[1].subjects[1].marks_scored.obtained_marks) 74.5 >>> print(student_list[1].subjects[3]) Introduction to Taxation >>> print(student_list[1].subjects[3].marks_scored) []
In this query, you’ll be retrieving the list of all student object with their marks by a particular subject.
Note
You can find complete documentation regarding Django querysets
Conclusion
In conclusion, you have come to an end of this post on Django Quersets | Backward, Reverse and Many To Many Relationships.
Comment below for more suggestions.




