Performance
- Advanced techniques to optimize Django applications for speed and scalability.
Why Performance Matters in Django?
Improves response time for users
Reduces server load and database queries
Critical for scalable applications
Prevents slow page loads in production
Query Optimization
Understanding Queries in Django ORM
Every ORM operation translates into SQL query
Too many queries → slows down app (N+1 problem)
Efficient queries → faster response, lower DB load
Tips for Query Optimization
Use select_related for foreign keys
Fetch related objects in single query
select_related Example
models.py
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
# views.py
books = Book.objects.select_related('author').all()
for book in books:
print(book.title, book.author.name)
2. Code Description
Fetches books and authors in one query
Avoids multiple DB hits
prefetch_related Example
authors = Author.objects.prefetch_related('book_set').all()
for author in authors:
for book in author.book_set.all():
print(author.name, book.title)
2. Code Description
Reduces extra queries when fetching related sets
Efficient for ManyToMany or reverse ForeignKey
Avoid unnecessary queries
# Bad
for book in Book.objects.all():
print(book.author.name) # extra query per book
# Good
books = Book.objects.select_related('author').all()
for book in books:
print(book.author.name)
- Use only() and defer() to load specific fields
Load Specific Fields
books = Book.objects.only('title') # load only title, skip author
Reduces data fetched from DB
ORM Efficiency
Use Aggregations & Annotations
Use Django ORM functions to perform calculations in DB
Reduces Python-side processing
ORM Aggregation
from django.db.models import Count
authors = Author.objects.annotate(book_count=Count('book'))
for author in authors:
print(author.name, author.book_count)
Description
Counts books per author in DB, not Python
More efficient for large datasets
Use values() and values_list() for lightweight queries
values Example
# Fetch only names of authors
names = Author.objects.values_list('name', flat=True)
Avoids fetching full model objects
Use Indexes for Heavy Queries
class Book(models.Model):
title = models.CharField(max_length=100, db_index=True)
Indexes speed up filter queries
Cache Frequently Accessed Data
Use Django cache framework:
from django.core.cache import cache
books = cache.get('all_books')
if not books:
books = list(Book.objects.all())
cache.set('all_books', books, 60*5) # cache 5 minutes
Reduces database hits for repeated queries
Profiling Queries
Check Queries Executed
from django.db import connection
books = Book.objects.all()
print(connection.queries)
Useful to identify N+1 problems
Use Django Debug Toolbar
Install: pip install django-debug-toolbar
Shows SQL queries per view
Highlights slow queries