Django 查询集求和

0 投票
1 回答
9444 浏览
提问于 2025-04-16 16:23

我需要对Django的查询集进行数据聚合。

我有一个模型,大概长这样:

class Model1(models.Model):
    ... some fields here ...

class Model2(models.Model):
    model1 = models.ForeignKey(Model1)
    number = models.IntegerField()
    active = models.BooleanField()
    category = models.CharField(choices=...)

这些都能正常工作,如果我在示例代码中漏掉了什么拼写错误也没关系。现在我想把model1和它相关的model2按类别分组显示。我是通过使用regroup模板标签来实现的(注意我有一个类方法叫做model2s,它返回的内容和model2_set.filter(active=True)是一样的):

{% regroup m1.model2s by category as m2_list %}

然后我像往常一样用regroup来显示它们。这些东西也都能正常工作。现在我需要在每个类别组的顶部添加一个总汇,显示该组的数字总和。所以如果我有两个属于同一类别的model2,引用了一个Model1,其中一个的数字是1,另一个的数字是2,那么我需要显示3。

实际上会有很多Model2,所以这个查询可能会比较耗费资源。

我查看了文档,看到有aggregate和annotate,但这两者似乎都不能让我按类别来求和。我希望不需要为每个类别都这样做:

m2sum = m1.model2s.filter(category='something').aggregate(Sum('number'))['number__sum']

有没有更简洁的方法来做到这一点,希望能和regroup很好地配合?

1 个回答

3

我觉得你可以用 annotate 这个方法来实现。 如果我找到一个好的例子,我会更新这个内容。

更新:我觉得可以这样做……如果我理解你的问题没错的话。 不过你应该用 Count 而不是 Avg。

Author.objects.values('name').annotate(average_rating=Avg('book__rating')) http://docs.djangoproject.com/en/dev/topics/db/aggregation/#values

撰写回答