Bird
Raised Fist0
Djangoframework~20 mins

Prefetch_related for reverse relations in Django - Practice Problems & Coding Challenges

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Challenge - 5 Problems
🎖️
Prefetch Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
component_behavior
intermediate
2:00remaining
What does prefetch_related do with reverse relations?

Consider two Django models: Author and Book, where Book has a foreign key to Author. If you use Author.objects.prefetch_related('book_set'), what is the main effect?

AIt does not affect the query and fetches authors without related books.
BIt joins the author and book tables in one query using SQL JOIN.
CIt fetches only the first book for each author to optimize performance.
DIt fetches all related books for each author in a single additional query, reducing database hits.
Attempts:
2 left
💡 Hint

Think about how Django avoids querying the database multiple times for related objects.

state_output
intermediate
2:00remaining
How many queries are executed with prefetch_related on reverse relation?

Given the models Author and Book (with Book.author as ForeignKey), what is the number of database queries executed by this code?

authors = Author.objects.prefetch_related('book_set').all()
for author in authors:
    print(len(author.book_set.all()))
ANo queries: data is fetched lazily when printing.
B1 query: a single JOIN query fetching authors and books.
C2 queries: one for authors and one for all related books.
DN+1 queries: one for authors and one per author for books.
Attempts:
2 left
💡 Hint

Remember how prefetch_related works internally with separate queries.

🔧 Debug
advanced
2:00remaining
Why does prefetch_related('books') raise an error on reverse relation?

Given models Author and Book where Book.author is a ForeignKey, what is wrong with this query?

Author.objects.prefetch_related('books').all()

Assuming no related_name is set on Book.author.

Aprefetch_related cannot be used on reverse relations without related_name.
BThe related name 'books' does not exist; the default reverse relation is 'book_set'.
CThe query will run but return empty related objects.
DThe query causes a syntax error due to missing parentheses.
Attempts:
2 left
💡 Hint

Check the default reverse relation name Django uses when no related_name is set.

📝 Syntax
advanced
2:00remaining
Which prefetch_related syntax correctly fetches nested reverse relations?

Given models Author, Book, and Chapter where Book has ForeignKey to Author and Chapter has ForeignKey to Book, which syntax correctly prefetches all books and their chapters for authors?

AAuthor.objects.prefetch_related('book_set__chapter_set').all()
BAuthor.objects.prefetch_related('book_set.chapter_set').all()
CAuthor.objects.prefetch_related(['book_set', 'chapter_set']).all()
DAuthor.objects.prefetch_related('book_set').prefetch_related('chapter_set').all()
Attempts:
2 left
💡 Hint

Think about how to specify nested relations in prefetch_related.

🧠 Conceptual
expert
3:00remaining
Why use Prefetch object with custom queryset on reverse relation?

When prefetching a reverse relation in Django, why might you use Prefetch with a custom queryset instead of a simple string?

ATo filter or order the related objects before they are attached to the main objects.
BTo force Django to use SQL JOIN instead of separate queries.
CTo disable caching of related objects for memory optimization.
DTo automatically update related objects in the database.
Attempts:
2 left
💡 Hint

Consider why you might want to control which related objects are fetched.

Practice

(1/5)
1. What is the main purpose of using prefetch_related with reverse relations in Django?
easy
A. To update related objects in bulk
B. To fetch related objects in a single query and reduce database hits
C. To delete related objects automatically
D. To create new related objects during query

Solution

  1. Step 1: Understand what prefetch_related does

    prefetch_related fetches related objects in a separate query but combines results in Python to reduce database hits.
  2. Step 2: Apply this to reverse relations

    Using prefetch_related on reverse relations loads all related objects efficiently, avoiding queries inside loops.
  3. Final Answer:

    To fetch related objects in a single query and reduce database hits -> Option B
  4. Quick Check:

    prefetch_related reduces queries [OK]
Hint: Remember: prefetch_related loads reverse relations in one go [OK]
Common Mistakes:
  • Thinking prefetch_related deletes or updates data
  • Confusing prefetch_related with select_related
  • Assuming it creates new objects automatically
2. Which of the following is the correct syntax to prefetch a reverse relation named comments on a Post model?
easy
A. Post.objects.prefetch_related(comments)
B. Post.objects.select_related('comments')
C. Post.objects.prefetch('comments')
D. Post.objects.prefetch_related('comments')

Solution

  1. Step 1: Recall the correct method name

    The correct method to prefetch related objects is prefetch_related, not prefetch or select_related for reverse relations.
  2. Step 2: Check the argument format

    The related name must be a string inside quotes, so 'comments' is correct, not a variable without quotes.
  3. Final Answer:

    Post.objects.prefetch_related('comments') -> Option D
  4. Quick Check:

    Correct method and string argument [OK]
Hint: Use prefetch_related('relation_name') with quotes [OK]
Common Mistakes:
  • Using select_related for reverse relations
  • Omitting quotes around relation name
  • Using a non-existent method like prefetch()
3. Given these models:
class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    author = models.ForeignKey(Author, related_name='books', on_delete=models.CASCADE)
    title = models.CharField(max_length=100)

What will this code print?
authors = Author.objects.prefetch_related('books')
for author in authors:
    print(author.name, [book.title for book in author.books.all()])
medium
A. Prints author names but book lists are empty
B. Raises an error because 'books' is not a valid relation
C. Prints each author name with a list of their book titles without extra queries
D. Prints author names but causes a query for each author inside the loop

Solution

  1. Step 1: Understand the model relation

    Each Author has many Book objects accessible via the reverse relation books.
  2. Step 2: Analyze the prefetch_related effect

    Using prefetch_related('books') loads all books for all authors in one extra query, so no queries happen inside the loop.
  3. Final Answer:

    Prints each author name with a list of their book titles without extra queries -> Option C
  4. Quick Check:

    prefetch_related loads reverse relations efficiently [OK]
Hint: prefetch_related loads reverse sets before looping [OK]
Common Mistakes:
  • Thinking prefetch_related causes errors if relation exists
  • Assuming empty lists because of missing select_related
  • Believing queries run inside the loop despite prefetch
4. What is wrong with this code snippet?
posts = Post.objects.prefetch_related('comment_set')
for post in posts:
    print(post.title, [c.text for c in post.comment_set.all()])

Assuming Comment model has a ForeignKey to Post without a related_name set.
medium
A. Using 'comment_set' is correct; no error here
B. Should use 'comments' instead of 'comment_set' in prefetch_related
C. Must use select_related instead of prefetch_related for reverse relations
D. The code will raise an AttributeError because 'comment_set' is invalid

Solution

  1. Step 1: Understand default reverse relation naming

    If no related_name is set on a ForeignKey, Django uses modelname_set as the reverse relation name, here comment_set.
  2. Step 2: Check usage in prefetch_related and loop

    Using prefetch_related('comment_set') and accessing post.comment_set.all() is correct and will work without error.
  3. Final Answer:

    Using 'comment_set' is correct; no error here -> Option A
  4. Quick Check:

    Default reverse name = modelname_set [OK]
Hint: Default reverse name is modelname_set if no related_name [OK]
Common Mistakes:
  • Assuming related_name is always 'comments'
  • Using select_related for reverse relations
  • Expecting an error when using default reverse name
5. You want to efficiently load all Author objects with their Book objects, but only books published after 2020. How do you use prefetch_related for this filtered reverse relation?
authors = Author.objects.prefetch_related( ... )
hard
A. Use Prefetch with a filtered queryset: Prefetch('books', queryset=Book.objects.filter(pub_year__gt=2020))
B. Use prefetch_related('books').filter(pub_year__gt=2020)
C. Use select_related('books').filter(pub_year__gt=2020)
D. Use prefetch_related('books__filter(pub_year__gt=2020)')

Solution

  1. Step 1: Understand filtering reverse relations with prefetch_related

    To filter related objects in prefetch_related, use the Prefetch object with a filtered queryset.
  2. Step 2: Apply Prefetch with filtered queryset

    Use Prefetch('books', queryset=Book.objects.filter(pub_year__gt=2020)) inside prefetch_related() to load only books after 2020.
  3. Final Answer:

    Use Prefetch with a filtered queryset: Prefetch('books', queryset=Book.objects.filter(pub_year__gt=2020)) -> Option A
  4. Quick Check:

    Filtered prefetch needs Prefetch object [OK]
Hint: Use Prefetch with filtered queryset inside prefetch_related [OK]
Common Mistakes:
  • Trying to filter directly inside prefetch_related string
  • Using select_related for many-to-one reverse relations
  • Filtering the main queryset instead of related queryset