The ForeignKey field is one of the most commonly used
relationship fields in Django. It is used to create a
many-to-one relationship between two models.
For example, one course can have many students, while each student can belong to one course.
ForeignKey creates a many-to-one relationship between two Django
models.
For example:
Course
↓
Many Students
One Course can have many Students, but each Student can point to one Course.
ForeignKey allows related database records to be connected without duplicating the complete information.
The basic syntax is:
field_name = models.ForeignKey(
ModelName,
on_delete=models.CASCADE
)
The first argument specifies the related model and
on_delete specifies what should happen when the related object
is deleted.
Suppose we have a Course model:
from django.db import models
class Course(models.Model):
name = models.CharField(
max_length=100
)
fee = models.IntegerField()
This model can store course information.
Now we can connect Student with Course using ForeignKey.
class Student(models.Model):
name = models.CharField(
max_length=100
)
course = models.ForeignKey(
Course,
on_delete=models.CASCADE
)
The course field connects each Student with a Course.
Suppose a Python course has three students:
Python
├── Rahul
├── Aman
└── Priya
There is one Course object and multiple Student objects connected to it. This is a many-to-one relationship.
The on_delete argument is required when defining a ForeignKey.
It controls what happens to related objects when the referenced object is
deleted.
course = models.ForeignKey(
Course,
on_delete=models.CASCADE
)
CASCADE causes related objects to be deleted when the referenced
object is deleted.
course = models.ForeignKey(
Course,
on_delete=models.CASCADE
)
For example, deleting a Course can delete the related Student records under this 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 a parent record should not be deleted while related records depend on it.
SET_NULL sets the ForeignKey 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 for this behavior.
SET_DEFAULT changes the ForeignKey value to its configured
default when the referenced object is deleted.
course = models.ForeignKey(
Course,
default=1,
on_delete=models.SET_DEFAULT
)
An appropriate default value must be configured.
DO_NOTHING tells Django not to perform an automatic action when
the referenced object is deleted.
course = models.ForeignKey(
Course,
on_delete=models.DO_NOTHING
)
The database may still enforce its own constraints, depending on the database configuration.
First create a Course object:
course = Course.objects.create(
name="Python",
fee=10000
)
The returned object can then be assigned to a Student.
You can assign the Course object directly to the ForeignKey field.
student = Student.objects.create(
name="Rahul",
course=course
)
Now the Student is connected to the Python Course.
Django also provides a database-oriented field attribute ending in
_id.
student = Student.objects.create(
name="Aman",
course_id=1
)
Here, 1 represents the primary key of the Course.
After retrieving a Student, you can access its Course through the ForeignKey field.
student = Student.objects.get(
id=1
)
print(student.course.name)
Django follows the relationship and returns the related Course object.
You can access the primary key of the related Course using
course_id.
print(student.course_id)
This gives the ID stored for the related Course.
A ForeignKey also provides a reverse relationship from the referenced model to the related objects.
course = Course.objects.get(
id=1
)
students = course.student_set.all()
By default, Django uses the related model name followed by
_set.
You can give the reverse relationship a custom name using
related_name.
course = models.ForeignKey(
Course,
on_delete=models.CASCADE,
related_name="students"
)
Now the reverse relationship can be accessed as:
course.students.all()
Django allows you to filter records using fields from the related model.
students = Student.objects.filter(
course__name="Python"
)
The double underscore connects the Student's ForeignKey with the Course's
name field.
You can filter students using the related Course ID.
students = Student.objects.filter(
course_id=1
)
This returns students whose Course has the specified primary key.
You can retrieve a related object using get().
course = Course.objects.get(
id=1
)
students = Student.objects.filter(
course=course
)
This returns students connected to that Course.
ForeignKey data can easily be displayed in Django templates.
<h3>{{ student.name }}</h3>
<p>
Course: {{ student.course.name }}
</p>
<p>
Fee: {{ student.course.fee }}
</p>
Django follows the relationship using dot notation.
A view can retrieve students and pass them to a template.
from django.shortcuts import render
from .models import Student
def student_list(request):
students = Student.objects.select_related(
"course"
)
return render(
request,
"students.html",
{"students": students}
)
select_related() is useful when retrieving objects along with
their ForeignKey relationships.
students = Student.objects.select_related(
"course"
).all()
It can reduce additional database queries when related Course information is needed for many Student objects.
Django Model Forms can automatically provide a form field for a ForeignKey.
from django import forms
from .models import Student
class StudentForm(forms.ModelForm):
class Meta:
model = Student
fields = [
"name",
"course"
]
The form can use available Course objects when selecting a course.
After adding or changing a ForeignKey field, migrations should normally be created and applied.
python manage.py makemigrations
python manage.py migrate
Django uses migrations to apply the model changes to the database schema.
from django.db import models
class Course(models.Model):
name = models.CharField(
max_length=100
)
fee = models.IntegerField()
def __str__(self):
return self.name
class Student(models.Model):
name = models.CharField(
max_length=100
)
course = models.ForeignKey(
Course,
on_delete=models.CASCADE,
related_name="students"
)
def __str__(self):
return self.name
In this example, one Course can have many Students.
on_delete argument.course with course_id.ForeignKey is an important Django relationship field used to connect many objects to one related object.
on_delete defines deletion behavior.CASCADE can delete related objects.PROTECT prevents deletion when protected relations exist.SET_NULL can set the relationship to NULL.related_name customizes reverse access.select_related() can optimize ForeignKey queries.ForeignKey creates a many-to-one relationship.on_delete controls what happens when a referenced object is deleted.related_name provides a custom reverse relationship name.course gives access to the related Course object.course_id gives the related Course primary key.select_related() is useful for efficiently loading ForeignKey relationships.Question: Which Django field is used to create a many-to-one relationship?