python / expert
Snippet
Django ORM Query Optimization with Prefetch Related
This expert pattern demonstrates advanced Django ORM optimization. Using Prefetch with a custom queryset filters related books before they're loaded into memory and uses select_related to fetch the publisher in the same query. The only() method limits the fields retrieved, reducing memory usage. A custom Manager encapsulates this logic, making it reusable across your application.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from django.db import modelsfrom django.db.models import Prefetchclass AuthorManager(models.Manager):def get_with_books(self):return self.get_queryset().prefetch_related(Prefetch('books',queryset=Book.objects.filter(is_published=True).select_related('publisher').only('id', 'title', 'published_date', 'publisher__name'),to_attr='published_books'))class Author(models.Model):name = models.CharField(max_length=200)objects = AuthorManager()class Meta:indexes = [models.Index(fields=['name'])]class Book(models.Model):author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')publisher = models.ForeignKey('Publisher', on_delete=models.CASCADE)is_published = models.BooleanField(default=False)
django
Breakdown
1
Prefetch('books', queryset=Book.objects.filter(...))
Creates a Prefetch object to control how related books are fetched and filtered
2
select_related('publisher')
Joins the publisher table in a single query, avoiding N+1 queries
3
only('id', 'title', 'published_date', 'publisher__name')
Limits retrieved columns to only what's needed, reducing data transfer
4
to_attr='published_books'
Stores prefetched results in a list attribute instead of the queryset cache
5
models.Index(fields=['name'])
Database-level index for faster lookups on the name field