首页 > 解决方案 > 是否有另一种方法来注释现有查询集中的计数/总和?

问题描述

让我用规范模型 Book&Author 来说明问题:

class Author(models.Model):
    name = models.CharField(max_length=100)

class Book(models.Model):
    name = models.CharField(max_length=300)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    authors = models.ManyToManyField(Author)
    status = models.CharField(max_length=50)
    date = models.DateField()    
    department = models.CharField(max_length=100)

这是视图:

class Report(ListView):
...
def get_queryset(self):
    ... # calculating of filters
    return Book.objects.filter(status='published', date= ... a bunch of filters)

这样我们就有了一个包含所有必要过滤器的查询集。它可能用于其他函数,例如,获取书籍的数量:

    def books_number(self):
        qs = self.get_queryset()
        return qs.count()

或所有这些书籍的费用:

    def summa(self):
        qs = self.get_queryset()
        return qs.aggregate(Sum('price'))

现在,我想获得每个作者的书籍数量及其成本,我会很高兴这样的事情:

    def authors_info(self):
        qs = self.get_queryset()
        return Author.objects.annotate(books_number=Count( use qs somehow ... ),
                                       books_cost = Sum( use qs over field 'price' somehow ...)
                                      )

但我还没有找到一种方法来做到这一点。

好吧,为了让它工作,我使用了这个:

    def authors_info(self):
        ... # calculating of THE SAME filters AGAIN

        q_ = Q(status='published', date= ... a bunch of filters)
        count_ = Count('book', filter=q_)
        sum_ = Sum('book__price', filter=q_)
        return Author.objects.annotate(books_number=count_,
                                       books_cost=sum_)

但它肯定与 DRY 原则相矛盾。

是否还有更简洁的方法可以在一个函数中获取查询集并在另一个函数中对其进行注释?

标签: django

解决方案


推荐阅读