django prefetch_related для нескольких взаимосвязей «один ко многим» с условиями фильтрации - PullRequest
0 голосов
/ 08 января 2020

Я бы хотел получить запрос prefetch_related, чтобы получить мои модели и все связанные с ними модели, следуя отношениям «один ко многим», но с условием фильтрации. Моя цель - использовать prefetch_related для получения всех моих моделей и связанных с ними моделей в одном django запросе (таким образом, не попадая в базу данных при переборе связанных моделей). Мне нужно go в направлении «один ко многим».

Скажем, у меня есть следующие простые модели Библиотеки, имеющие много Книг, имеющих много Страниц.

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)

Я знаю, что могу сделать models.Library.objects.prefetch_related('book_set__page_set'), чтобы получить все в один прием, но что, если я хочу ограничить бронирование с genre='fantasy'? Как я могу добавить это условие фильтра в мой запрос предварительной выборки, охватывающий отношения?

Ответы [ 2 ]

1 голос
/ 08 января 2020

Вы хотите следовать инструкциям здесь:

https://docs.djangoproject.com/en/2.2/ref/models/querysets/#prefetch -объекты

В основном вы будете делать что-то вроде этого

books_query = Books.objects.filter(genre="fantasy")
pf = Prefetch("book_set", queryset=books_query)
Library.objects.prefetch_related(pf).get().book_set.all()
0 голосов
/ 10 января 2020

Дополняет ответ @themanatuf, в котором отсутствует предварительная выборка связанных моделей страниц. Приведенный ниже код запроса будет выполнять предварительную выборку всех моделей Библиотеки с соответствующими книгами и страницами, но ограничиваясь Книгой жанра = '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()
...