Django 查询集:切片后聚合无效

4 投票
3 回答
1485 浏览
提问于 2025-04-17 17:41
Car.objects.all() # 5 cars in db, every car costs 1000 $

Car.objects.all().aggregate(Sum("price")) # result: 5000

# aggregate only on a subset

Car.objects.all()[3:].aggregate(Sum("price")) # result: 5000!, not 3000

# with filter()[3:] i got the same results!

为什么?切片在数据库中没有被计算?

我该如何用聚合来实现这个?

3 个回答

0

从Django 1.7版本开始(也就是2014年),你可以对一部分数据进行汇总。

5

看起来在切片操作上使用聚合功能是不行的,就像这个开放的票据所提到的:https://code.djangoproject.com/ticket/12886

一种解决办法是执行两个不同的查询。第一个查询用来获取一部分汽车数据,第二个查询则用来进行聚合操作:

qs = Car.objects.all()[:3]
sub_sum = Car.objects.filter(pk__in=qs).aggregate(Sum("price"))
3

aggregate 的工作原理是修改发送给数据库的查询,这样聚合操作就会在数据库那边进行。你有两个选择。

  1. 你可以在使用 aggregate 之前,先用 filter 来减少你的查询集,而不是通过切片来减少。
  2. 你需要在 Python 中进行聚合,比如在切片之后使用 sum(car.price for car in cars)。一旦你进行了切片,查询就会发送到数据库,这样你就不能再通过 ORM(也就是查询集的方法)进行聚合了。

撰写回答