【问题标题】:Filter output items of reverse relations in Django过滤Django中反向关系的输出项
【发布时间】:2021-11-02 00:05:44
【问题描述】:

我有这些模型:

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框架序列化器):

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 过滤器会影响输出作者和书籍数量,但不会影响作者的书籍。我的意思是对于每个作者,所有的书都会被退回,而不仅仅是在指定范围内出版的书。

我怎样才能过滤具有指定参数的书籍?

【问题讨论】:

    标签: django django-models django-rest-framework django-queryset


    【解决方案1】:

    您可以使用Prefetch 对象:

    from django.db.models import Prefetch
    
    Author.objects.filter(
        books__published_at__range=[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 列表也将仅包含这些书籍。

    【讨论】:

    • books_count 将确定该范围内出版的图书数量。我说的对吗?
    • @AminA2: 是的,正如在代码片段正下方指定的那样。您的查询集中也是如此。
    • @AminA2:所以你的问题中的“每个作者出版的书籍数量”并不完全正确:它会计算给定出版的书籍数量日期时间范围。 Prefetch 对 .annotate(...) 和 .aggregate(..)s 等没有影响:因为书籍是在第二个独立查询中获取的。
    猜你喜欢
    • 2016-04-23
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 2019-11-06
    • 2020-09-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    相关资源
    最近更新 更多