I would like to to a prefetch_related query to get my models and all related models by following one-to-many relations, but with a filtering condition. My goal is to use prefetch_related to obtain all my models and related models in one django query (thus not hitting the database when iterating through related models). I need to go in the one-to-many direction.
Say I have the following simple models of Library having many Books having many Pages.
from django.db import models
class Library(models.Model):
name = models.CharField(max_length=50)
class Book(models.Model):
title = models.CharField(max_length=50)
genre = models.CharField(max_length=50)
library = models.ForeignKey(Library, on_delete=models.CASCADE)
class Page(models.Model):
content = models.TextField()
book = models.ForeignKey(Book, on_delete=models.CASCADE)
I know I can do models.Library.objects.prefetch_related('book_set__page_set')
to get everything one-shot, but what if I want to restrict to book with genre='fantasy'
? How can I add this filter condition in my relation-spanning prefetch query?
You'll want to follow the instructions here:
https://docs.djangoproject.com/en/2.2/ref/models/querysets/#prefetch-objects
Basically you'll do something like this
books_query = Books.objects.filter(genre="fantasy")
pf = Prefetch("book_set", queryset=books_query)
Library.objects.prefetch_related(pf).get().book_set.all()
Complementing @themanatuf answer which was missing the prefetching of related Page models. Query code below will prefetch all Library models with their related Books and Pages, but restricting to Book genre='fantasy':
pf_queryset = models.Book.objects.filter(genre="fantasy").prefetch_related("page_set")
pf = Prefetch("book_set", queryset=pf_queryset)
models.Library.objects.prefetch_related(pf).all()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.