In real-world applications, database tables are often connected to each other. For example, a student can belong to a course, an employee can belong to a department, and an order can contain multiple products.
Django provides relationship fields such as ForeignKey,
OneToOneField, and ManyToManyField to represent
these connections between models.
A model relationship connects one database model with another model.
For example, a Student can belong to a Course:
Student → Course
Instead of storing all course information repeatedly inside every student record, Django can use a relationship field.
Relationships help organize related data efficiently.
Django provides three commonly used relationship fields:
ForeignKey – many-to-one relationship.OneToOneField – one-to-one relationship.ManyToManyField – many-to-many relationship.Each relationship type is useful for a different database design.
A one-to-many relationship means one object can be related to many other objects.
For example:
One Course
↓
Many Students
A course can have many students, while each student belongs to one course.
This is commonly implemented using ForeignKey.
A one-to-one relationship means one object is associated with exactly one object on the other side.
For example:
User
↓
One Profile
A user can have one profile, and that profile belongs to one user.
A many-to-many relationship means multiple objects can be related to multiple objects.
For example:
Students ←→ Courses
A student can enroll in multiple courses, and a course can contain multiple students.
The ForeignKey field is used to create a many-to-one
relationship.
class Course(models.Model):
name = models.CharField(
max_length=100
)
class Student(models.Model):
name = models.CharField(
max_length=100
)
course = models.ForeignKey(
Course,
on_delete=models.CASCADE
)
The on_delete argument specifies what should happen to related
objects when the referenced object is deleted.
course = models.ForeignKey(
Course,
on_delete=models.CASCADE
)
Different deletion behaviors can be selected depending on the application's requirements.
With CASCADE, deleting the referenced object can also delete
related objects.
course = models.ForeignKey(
Course,
on_delete=models.CASCADE
)
For example, deleting a Course can cause related Student records to be deleted according to the relationship configuration.
PROTECT prevents deletion of the referenced object when
protected related objects exist.
course = models.ForeignKey(
Course,
on_delete=models.PROTECT
)
This is useful when related records should prevent the parent object from being deleted.
SET_NULL sets the relationship field to NULL when the referenced
object is deleted.
course = models.ForeignKey(
Course,
null=True,
on_delete=models.SET_NULL
)
The field must allow NULL values when using this option.
SET_DEFAULT sets the relationship field to its configured
default value when the referenced object is deleted.
course = models.ForeignKey(
Course,
default=1,
on_delete=models.SET_DEFAULT
)
The field must have an appropriate default value.
First create a Course object:
course = Course.objects.create(
name="Python"
)
Then create a Student associated with that course:
student = Student.objects.create(
name="Rahul",
course=course
)
If Student has a ForeignKey named course, you can access the
related Course object through the student.
student = Student.objects.get(
id=1
)
print(student.course.name)
Django follows the relationship and retrieves the related Course object.
You can also access students from a Course object using the default reverse relationship.
course = Course.objects.get(
id=1
)
students = course.student_set.all()
The default reverse manager is based on the related model name.
The related_name option allows you to give the reverse
relationship a custom name.
course = models.ForeignKey(
Course,
on_delete=models.CASCADE,
related_name="students"
)
Now you can access students using:
course.students.all()
Django allows you to filter records using fields from related models.
students = Student.objects.filter(
course__name="Python"
)
The double underscore connects the Student field to the Course field.
OneToOneField creates a one-to-one relationship between two
models.
class Profile(models.Model):
user = models.OneToOneField(
User,
on_delete=models.CASCADE
)
phone = models.CharField(
max_length=20
)
Each User can have one related Profile.
A related profile can be accessed directly from the user.
user = User.objects.get(
id=1
)
print(user.profile.phone)
The reverse accessor is based on the relationship configuration and model name unless a custom related name is provided.
ManyToManyField is used when multiple objects can be connected
to multiple objects.
class Course(models.Model):
name = models.CharField(
max_length=100
)
class Student(models.Model):
name = models.CharField(
max_length=100
)
courses = models.ManyToManyField(
Course
)
After creating a Student and Course, you can connect them using
add().
student.courses.add(
course
)
Multiple courses can be added:
student.courses.add(
course1,
course2
)
You can retrieve all courses associated with a student.
courses = student.courses.all()
for course in courses:
print(course.name)
The result is a QuerySet of related Course objects.
The remove() method removes a relationship without deleting the
related objects themselves.
student.courses.remove(
course
)
The Course object still exists; only the connection is removed.
The clear() method removes all many-to-many relationships from
an object.
student.courses.clear()
This removes all Course connections for the student without deleting the Course objects.
The set() method can replace the current relationships with a
new collection.
student.courses.set(
[course1, course2]
)
The student's course relationships are replaced by the specified courses.
select_related() can be used with ForeignKey and OneToOne
relationships to retrieve related objects efficiently in the same query
pattern.
students = Student.objects.select_related(
"course"
).all()
This is useful when each student needs its related course information.
prefetch_related() is useful for efficiently retrieving related
objects, including many-to-many and reverse relationships.
students = Student.objects.prefetch_related(
"courses"
).all()
It helps reduce unnecessary database queries when displaying related data.
| Relationship | Example |
|---|---|
ForeignKey |
Many Students → One Course |
OneToOneField |
One User → One Profile |
ManyToManyField |
Many Students ↔ Many Courses |
Choose the relationship based on how the real-world data is connected.
on_delete argument for ForeignKey.select_related() or prefetch_related() when appropriate.Django relationships allow models to represent connections between database tables.
ForeignKey represents a many-to-one relationship.OneToOneField represents a one-to-one relationship.ManyToManyField represents a many-to-many relationship.on_delete controls behavior when referenced objects are deleted.related_name can customize reverse relationship access.add(), remove(), clear(), and set() manage many-to-many relationships.select_related() is useful for ForeignKey and OneToOne relationships.prefetch_related() is useful for many-to-many and reverse relationships.ForeignKey is used for many-to-one relationships.OneToOneField is used for one-to-one relationships.ManyToManyField is used for many-to-many relationships.on_delete defines behavior when related objects are deleted.related_name provides a custom reverse relationship name.select_related() can optimize ForeignKey and OneToOne queries.prefetch_related() can optimize many-to-many and reverse relationships.Question: Which Django field is commonly used to create a many-to-one relationship?