Фильтр элементов вывода обратных отношений в Django
У меня есть эти модели:
class Author(models.Model):
name = models.CharField(max_length=50)
class Book(models.Model):
name = models.CharField(max_length=150)
author = models.ForeignKey(Author, on_delete=models.CASCADE, related_name="books")
published_at = models.DateField()
Вот мой запрос:
Author.objects.filter(books__published_at__ragne=[date_from, date_to]).annotate(books_count=Count('books'))
Вывод запроса будет отправлен в следующий сериализатор (наследующий сериализатор django rest framework):
class AuthorSerializer(serializers.ModelSerializer):
books_count= serializers.IntegerField(read_only=True)
books = serializers.StringRelatedField(many=True)
class Meta:
model = Author
fields = ['id', 'name', 'books_count', 'books']
На выходе AuthorSerializer будут представлены все авторы, у которых есть хотя бы одна опубликованная книга в указанном диапазоне, с количеством книг, опубликованных каждым автором, а также строковое представление всех книг каждого автора.
Фильтр books__published_at__ragne
влияет на выводимых авторов и количество книг, но не влияет на книги авторов. То есть для каждого автора возвращаются все книги, а не только те, которые опубликованы в указанном диапазоне.
Как я могу также отфильтровать книги с указанными параметрами?
Вы можете работать с Prefetch
объектом:
from django.db.models import Prefetch
Author.objects.filter(
books__published_at__ragne=[date_from, date_to]
).annotate(books_count=Count('books')).prefetch_related(
Prefetch(
'books',
queryset=Book.objects.filter(published_at__ragne=[date_from, date_to])
)
)
Это означает, что books_count
будет определять количество книг, опубликованных в этом диапазоне, и список books
также будет содержать только эти книги.