Фильтр элементов вывода обратных отношений в 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 также будет содержать только эти книги.

Вернуться на верх