简体   繁体   English

Django查询集:切片查询集后聚合不起作用

[英]Django queryset: aggregate after slicing the queryset doesn't work

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!

Why?为什么? Slicing is not evaluated in db?切片不在数据库中评估?

How can i achieve that with aggregate?我怎样才能用聚合来实现呢?

It seems it is not possible to use aggregation on slicing as this open ticket suggest: https://code.djangoproject.com/ticket/12886似乎不可能在切片上使用聚合,因为这个开放票建议: https ://code.djangoproject.com/ticket/12886

One solution is to execute two distinct queries.一种解决方案是执行两个不同的查询。 The first one to retrieve the sub set of Cars and the second one to actually perform the aggregation:第一个检索 Cars 的子集,第二个实际执行聚合:

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

aggregate works by modifying the query sent to the DB, causing aggregation to happen on the DB side. aggregate通过修改发送到数据库的查询来工作,导致聚合发生在数据库端。 You have two choices.你有两个选择。

  1. You can use filter to reduce your QuerySet before using aggregate , instead of slicing to reduce it.您可以在使用之前使用filter来减少您的 QuerySet aggregate ,而不是通过切片来减少它。
  2. You have to do your aggregation in Python, eg sum(car.price for car in cars) after slicing.切片后,您必须在 Python 中进行聚合,例如sum(car.price for car in cars) Once you slice, the query is sent to the database, so you can no longer aggregate through the ORM (ie QuerySet methods).切片后,查询将发送到数据库,因此您不能再通过 ORM(即 QuerySet 方法)进行聚合。

从 Django 1.7(早在 2014 年)开始,您可以聚合切片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM