Using prefetch_related for Optimization

A snippet showing how to use prefetch_related for optimizing many-to-many queries.


# models.py

from django.db import models

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

    def __str__(self):
        return self.name

class Book(models.Model):
    title = models.CharField(max_length=200)
    authors = models.ManyToManyField(Author, related_name='books')

    def __str__(self):
        return self.title
  

# views.py

from django.shortcuts import render
from .models import Book

def book_list_without_prefetch(request):
    books = Book.objects.all()  # This will cause N+1 queries when accessing authors
    book_info = [(book.title, [author.name for author in book.authors.all()]) for book in books]
    return render(request, 'books.html', {'book_info': book_info})
    # Each book.authors.all() triggers extra queries

def book_list_with_prefetch(request):
    books = Book.objects.prefetch_related('authors')  # Efficiently fetches related authors
    book_info = [(book.title, [author.name for author in book.authors.all()]) for book in books]
    return render(request, 'books.html', {'book_info': book_info})
    # Authors are prefetched; no extra queries per book
  
Explanation:
  • prefetch_related() fetches many-to-many and reverse relations efficiently using separate queries plus an in-memory join.
  • Avoids the N+1 problem when iterating and accessing related collections like b.authors.all().
  • Best for many-to-many or one-to-many reverse lookups; use select_related() for FK/OneToOne.
  • You can prefetch nested paths, e.g., prefetch_related('authors__profile') with a custom Prefetch for filtering.
  • Category Models & ORM
  • Total Views 1173
  • Last Modified 10 November, 2025
  • Tags #queryset #optimization #prefetch_related #orm
Never miss a story on Django.wiki

Subscribe for fresh tutorials, snippets, and updates.

By subscribing you agree to our Privacy Policy.