Prefetch_related and select_related functions in django
Last Updated :
06 Jan, 2023
In Django, select_related and prefetch_related are designed to stop the deluge of database queries that are caused by accessing related objects. In this article, we will see how it reduces the number of queries and make the program much faster.
- select_related() "follows" foreign-key relationships, selecting additional related-object data when it executes its query.
- prefetch_related() does a separate lookup for each relationship and does the "joining" in Python.
One uses select_related when the object that you're going to be selecting is a single object, so OneToOneField or a ForeignKey. You use prefetch_related when you're going to get a "set" of things, so ManyToManyFields as you stated or reverse ForeignKeys. Just to clarify what I mean by "reverse ForeignKeys".
Example to illustrate the concept of Prefetch_related and select_related -
The above classification might be not so clear let's see an example:
Python3
class ModelA(models.Model):
pass
class ModelB(models.Model):
a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
# Forward ForeignKey relationship
ModelB.objects.select_related('a').all()
# Reverse ForeignKey relationship
ModelA.objects.prefetch_related('modelb_set').all()
select_related obtains all data at one time through multi-table join Association query and improves performance by reducing the number of database queries. It uses JOIN statements of SQL to optimize and improve performance by reducing the number of SQL queries. The latter is to solve the problem in the SQL query through a JOIN statement. However, for many-to-many relationships, it is not wise to use SQL statements to solve them, because the tables obtained by JOIN will be very long, which will lead to an increase in running time and memory occupation of SQL statements. The solution to prefetch_related() is to query each table separately and then use Python to handle their relationship!
Here are some examples :
Models.py reads as follows:
Python3
from django.db import models
class Province(models.Model):
name = models.CharField(max_length = 10)
def __unicode__(self):
return self.name
class City(models.Model):
name = models.CharField(max_length = 5)
province = models.ForeignKey(Province)
def __unicode__(self):
return self.name
class Person(models.Model):
firstname = models.CharField(max_length = 10)
lastname = models.CharField(max_length = 10)
visitation = models.ManyToManyField(City, related_name = "visitor")
hometown = models.ForeignKey(City, related_name = "birth")
living = models.ForeignKey(City, related_name = "citizen")
def __unicode__(self):
return self.firstname + self.lastname
select_related -
we use the select_related() function:
>>> citys = City.objects.select_related().all()
>>> for c in citys:
... print c.province
...
There is only one SQL query, which obviously greatly reduces the number of SQL queries:
SELECT `Optimize_city`.`id`, `Optimize_city`.`name`,
`Optimize_city`.`province_id`, `Optimize_province`.`id`, `Optimize_province`.`name`
FROM`Optimize_city`
INNER JOIN `Optimize_province` ON
(`Optimize_city`.`province_id`=`Optimize_province`.`id`);
prefetch_related -
Here we can see that Django uses INNER JOIN. I would like to clear one thing that Optimize is a name of our app. If we want to get all the city names of Hubei, we can do this:
> hb=Province.objects.prefetch_related('city_set').get(name__iexact=u"Hubei Province")
>>> for city in hb.city_set.all():
... city.name
...
Triggered SQL queries:
SELECT `Optimize_province`.`id`, `Optimize_province`.`name`
FROM `Optimize_province`
WHERE `Optimize_province', `name `LIKE'Hubei Province';
SELECT `Optimize_city`.`id`, `Optimize_city`.`name`, `Optimize_city`.`province_id`
FROM `Optimize_city`
WHERE `Optimize_city`.`province_id` IN (1);
As we can see, prefetch is implemented using the IN statement. In this way, when there are too many objects in QuerySet, performance problems may arise depending on the characteristics of the database.
Similar Reads
Update View - Function based Views Django
Update View refers to a view (logic) to update a particular instance of a table from the database with some extra details. It is used to update entries in the database for example, updating an article at geeksforgeeks. So Update view must display the old data in the form and let user update the data
4 min read
List View - Function based Views Django
A List View is a type of Django view used to display multiple instances of a model (i.e., rows from a database table). It is commonly used when you need to present a list of items on a page, for example, listing products on an eCommerce site. While Django provides built-in support for List Views usi
3 min read
Render Model in Django Admin Interface
Rendering model in admin refers to adding the model to the admin interface so that data can be manipulated easily using admin interface. Django's ORM provides a predefined admin interface that can be used to manipulate data by performing operations such as INSERT, SEARCH, SELECT, CREATE, etc. as in
2 min read
The Future of Django in 2025 [Top Trends and Predictions]
Have you ever wondered at the excellence of popular internet giants like Instagram, Spotify, Dropbox, and Pinterest in creating robust and flexible web applications? The secret lies in Django, a high-level Python web framework that empowers developers to create superior web applications with ease.In
9 min read
Django Function Based Views
Django is a Python-based web framework which allows you to quickly create web application without all of the installation or dependency problems that you normally will find with other frameworks. Django is based on MVT (Model View Template) architecture and revolves around CRUD (Create, Retrieve, Up
7 min read
related_name - Django Built-in Field Validation
The related_name attribute specifies the name of the reverse relation from the User model back to your model. If you don't specify a related_name, Django automatically creates one using the name of your model with the suffix _set. Syntax: field_name = models.Field(related_name="name") Explanation: I
3 min read
Include Related Model Fields In Django Rest Framework
In Django Rest Framework (DRF), it is common to work with related models, especially when building APIs that expose complex data structures. We might need to include data from related models (like foreign keys and many-to-many relationships) in our serialized API responses. DRF provides powerful mec
3 min read
How to Perform Query Filtering in Django Templates
Sometimes we may want to filter or modify the list of objects within the template itself to tailor the data being displayed. While filtering should generally be done at the view level for clarity and separation of concerns, Django templates provide some basic filtering capabilities through template
5 min read
How To Filter A Nested Serializer In Django Rest Framework?
When building APIs with Django Rest Framework (DRF), nested serializers are commonly used to represent relationships between models. A nested serializer allows us to include data from related models within a serializer. However, there are instances where we might want to filter the data returned by
6 min read
The Most Efficient Way to Store a List in Django Models
Django offers several ways of storing lists inside models. All of this depends on the database we are using and what actually meets our use case in an application. Whether we're using PostgreSQL, require flexibility with JSON structures, or prefer custom implementations, each has its pros and cons o
5 min read