TGViewer
Engineering Notes Engineering Notes @boboshersnotes · 2.61K subscribers
Post #172 936
Engineering Notes #question What are prefetch_related() and select_related() in django querysets and how they work?
Well, most of the time you wanna retrieve data from more than one table. In that case, you need an efficient way to play with more than just one model.

Let's say you have a Book model that has a ForeignKey relationship to Author model. You wanna get information about all books and their authors in a single view.

Let's say you have n books. You'll get all Book objects with a single DB query via Book.objects.all() queryset.
But each time you ask for the author of a book, django makes another DB query to retrieve information about the author of this book. In total, django performs n+1 queries: 1 query to get all the books and n queries to get authors of n books. This is what they call n+1 problem.

This is where prefetch_related() and select_related() come into the picture.
They have different purposes and they work differently.

1. select_related() simply makes a SQL JOIN for each selected relationship in a model. In simple words, you'll get data from multiple tables within a single query. For the example above, it joins the author table to the book table with book.author_id = author.id condition.
Instead of n+1 queries, you'll make 1 complex query to retrieve all the necessary data.
select_related() is limited to a single relationship level. This means, it can be used for first-level one-to-one and many-to-one relationships. If you have this kinda relationship:
Book -> Author -> User,
You cannot get data in User model from Book, because they don't have a direct relationship between them.

2. prefetch_related() is designed for more than 1 level relationship (like Author, Book, User example). Since it's not a direct relationship, you cannot make a SQL JOIN here. What prefetch_related() does is simply doing a separate query for each relationship, but all in a single batch.
You might be wondering then how it could be different from the usual way, if still it makes a separate query for each relationship. For example, if you loop through all the books and access to its author, django makes a query at the moment where you ask for it, which kills the performance. On the other hand, a queryset using prefetch_related fetches all the necessary data when you ask for all the books and author will be already there when you ask for them.
Since many-to-many relationship is technically combination of 2 foreignkeys, you cannot use select_related() with them. Here what you need is prefetch_related().
  • 👍 3
More from @boboshersnotes
  1. Oct 7, 2026– How much customization do you need? – Yes
  2. Oct 5, 2026I pinch the airpods once, Youtube video on my laptop is paused. I pinch it again, the vide…
  3. Oct 5, 2026The smartest kids in Kazakhstan should not be doing AI or maxxing out Claude. AI products…
  4. Sep 28, 2026https://www.youtube.com/watch?v=9HIy5dJE-zQ
  5. Sep 22, 2026spa-net.com qiziq challange ekan, kun bo'yi "enter" bosishdan zerikkanda bosh qotirib ko'r…
  6. Sep 21, 2026Bizda odatda juma kunlarining ikkinchi yarmi ishga to'g'ridan-to'g'ri aloqador bo'lmagan n…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →