Working With Select_Related In Django

Working With Select_Related In Django

select_related is a queryset method in Django which returns new queryset result for a Django Model. select_related is more helpful in foreign-key relationships. It is useful when we are going to use those foreign-key relationship data later in our code. select_related is a preformance booster, which caches the result for the foreign-key relationships, so that django ORM do not need to query again to get the data for the foreign-key relationships.

select_related creates a single complex query using joins on related models and retrives the data at once and caches it for later use, So foreign-key relationships won't require database queries.

Example Use Case:

lets consider below models

class ClassRoom(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

class Student(models.Model):
    name = models.CharField(max_length=100)
    class_room = models.ForeignKey(ClassRoom, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

let's consider below queries

query1 = Student.objects.all()
for student in query1:
    print(student.name)
    print(student.class_room.name)  # queries the database for relational data
query2 = Student.objects.all().select_related()
for student in query2:
  print(student.name)
  print(student.class_room.name) # no database query

In above code when we use the query1 it generates the SQL code like below

SELECT
    "myapp_student"."id", "myapp_student"."name",
    "myapp_student"."class_room_id"
FROM
    "myapp_student"

In above code when we use the query2 it generates the complex SQL code like below

SELECT
  "myapp_student"."id", "myapp_student"."name",
  "myapp_student"."class_room_id", "myapp_classroom"."id",
  "myapp_classroom"."name"
FROM "myapp_student"
INNER JOIN "myapp_classroom" ON ("myapp_student"."class_room_id" = "myapp_classroom"."id")

In the query2 django is joining the foreign key relationships so, when foreign key data is required then django ORM will not hit the database. query1 results in 1 + number of records queries to the database where as in query2 it results in only 1 database query. So, It's recommended to use the select_related when we use foreign key related data.