Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 942
apelliciari Avatar asked Dec 26 '22 08:12

apelliciari


2 Answers

It seems it is not possible to use aggregation on slicing as this open ticket suggest: 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:

qs = Car.objects.all()[:3]
sub_sum = Car.objects.filter(pk__in=qs).aggregate(Sum("price"))
like image 161
El Bert Avatar answered Dec 28 '22 22:12

El Bert


aggregate works by modifying the query sent to the DB, causing aggregation to happen on the DB side. You have two choices.

  1. You can use filter to reduce your QuerySet before using aggregate, instead of slicing to reduce it.
  2. You have to do your aggregation in Python, e.g. sum(car.price for car in cars) after slicing. Once you slice, the query is sent to the database, so you can no longer aggregate through the ORM (i.e. QuerySet methods).
like image 32
acjay Avatar answered Dec 28 '22 22:12

acjay