Performance: Relationship query patterns
This affects how quickly related data loads and how many database queries are made, impacting page load speed and responsiveness.
Jump into concepts and practice - no test required
posts = Post.objects.select_related('author').all() for post in posts: author_name = post.author.name # no extra queries
posts = Post.objects.all() for post in posts: author_name = post.author.name # triggers a query per post
| Pattern | Database Queries | Query Count | Page Load Impact | Verdict |
|---|---|---|---|---|
| No related optimization | Multiple queries per related object | 1 + N | High latency, slow LCP | [X] Bad |
| select_related for foreign keys | Single join query | 1 | Fast data fetch, better LCP | [OK] Good |
| prefetch_related for many-to-many | Two queries with caching | 2 | Efficient for many-to-many, good LCP | [OK] Good |
Book objects where the related Author model's name is 'Alice'?author__name='Alice' correctly filters books whose author's name is 'Alice'.select_related to optimize a query fetching Book objects with their related Author data?select_related accepts one or more string arguments naming related fields to follow.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)books = Book.objects.filter(author__name__startswith='J')
author__name__startswith='J', which means it looks at the related author's name starting with 'J'.Book objects whose related Author name starts with 'J'.Book.objects.prefetch_related('author__books').all()Author has a reverse relation books to Book.prefetch_related supports double-underscore chained lookups across forward (FK) and reverse relations.Book, 'author' follows the FK to Author, then 'books' follows the reverse relation to Book objects. This is valid and prefetches all books per author.Book objects along with their Author and the Publisher related to the author. The models are:class Publisher(models.Model):
name = models.CharField(max_length=100)
class Author(models.Model):
name = models.CharField(max_length=100)
publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE)
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(Author, on_delete=models.CASCADE)select_related follows foreign keys with SQL JOINs, efficient for single-valued relations. prefetch_related is for many-to-many or reverse relations.author and author__publisher are foreign keys (single-valued), so select_related is best to reduce queries.