Django, как фильтровать экземпляры модели, а также связанные объекты для каждого экземпляра. Вложенная фильтрация?

#python #django

Вопрос:

У меня есть три модели, Жанр, Фильм и Обзор. В каждом жанре может быть несколько фильмов, и каждый фильм может иметь несколько обзоров. Я пытался отфильтровать связанные объекты экземпляра жанра таким образом, чтобы набор запросов содержал только активные фильмы, и каждый из этих активных фильмов содержал только активные обзоры.

models.py

 class Genre(models.Model):
    name = models.CharField(max_length=160)


class Movie(models.Model):
    genre = models.ForeignKey(Genre, null=True, on_delete=models.CASCADE, related_name='movies')
    title = models.CharField(max_length=160)
    active = models.BooleanField(default=True)


class Review(models.Model):
    movie = models.ForeignKey(Movie, null=True, on_delete=models.CASCADE, related_name='reviews')
    author = models.CharField(max_length=150)
    active = models.BooleanField(default=True)
 

Как я могу получить набор запросов из экземпляра жанра, который содержит только активные фильмы и обзоры? Спасибо за уделенное время!

редактировать: Моя цель состоит в том, чтобы использовать этот набор запросов для извлечения каждого активного фильма, а затем для каждого активного фильма извлекать каждый активный обзор. Итак, я ищу решение, которое дает набор запросов, который можно легко повторить в порядке сначала активных фильмов, а затем активных обзоров.

Ответ №1:

Вы можете .filter(…) [Django-doc] с:

 Review.objects.filter(active=True, movie__active=True, movie__genre=genre1) 

Можно использовать двойные подчеркивания ( __ ) для просмотра «сквозных» отношений.

Если вы хотите получить Movie s и только активные отзывы, мы можем работать с Prefetch объектом:

 from django.db.models import Prefetch

Movie.objects.filter(active=True, genre=genre1).prefetch_related(
    Prefetch(
        'reviews',
        queryset=Review.objects.filter(active=True),
        to_attr='active_reviews'
    )
) 

Movie s, возникающие в результате этого набора запросов, будут иметь атрибут .active_review s, содержащий только активные отзывы.