149

I have a model:

class ItemPrice(models.Model):
     price = models.DecimalField(max_digits=8, decimal_places=2)
     # ...

I tried this to calculate the sum of price in this queryset:

items = ItemPrice.objects.all().annotate(Sum('price'))

What's wrong in this query? or is there any other way to calculate the Sum of price column?

I know this can be done by using for loop on queryset but i need an elegant solution.

Thanks!

1
  • Does this answer your question? Django SUM Query? Commented Aug 6, 2020 at 13:42

8 Answers 8

316

You're probably looking for aggregate

from django.db.models import Sum

ItemPrice.objects.aggregate(Sum('price'))
# returns {'price__sum': 1000} for example
Sign up to request clarification or add additional context in comments.

2 Comments

How can i get total count whose price=5000 ?
Remember returns dictionary not float/integer e.g. {'price__sum':1000} . Can get float/integer with yourdict['price__sum']
67

Use .aggregate(Sum('column'))['column__sum'] reefer my example below

sum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']

1 Comment

I am getting an error : 'decimal.Decimal' object is not iterable
54

Annotate adds a field to results:

>> Order.objects.annotate(total_price=Sum('price'))
<QuerySet [<Order: L-555>, <Order: L-222>]>

>> orders.first().total_price
Decimal('340.00')

Aggregate returns a dict with asked result:

>> Order.objects.aggregate(total_price=Sum('price'))
{'total_price': Decimal('1260.00')}

1 Comment

I appreciate you showing how to specify the key to store the sum value into.
11

Using cProfile profiler, I find that in my development environment, it is more efficient (faster) to sum the values of a list than to aggregate using Sum(). eg:

sum_a = sum([item.column for item in queryset]) # Definitely takes more memory.
sum_b = queryset.aggregate(Sum('column')).get('column__sum') # Takes about 20% more time.

I tested this in different contexts and it seems like using aggregate takes always longer to produce the same result. Although I suspect there might be advantages memory-wise to use it instead of summing a list.

2 Comments

Alternatively, use a generator expression instead of a list: sum_a = sum(item.column for item in queryset). The only difference is the removed []s. This saves the memory space for calculating the entire list before sum() iterates over it.
getting an error : 'decimal.Decimal' object is not iterable
9

Previous answers are pretty well, also, you may get that total with a line of vanilla code...

items = ItemPrice.objects.all()
total_price = sum(items.values_list('price', flat=True))

Comments

4

You could also get the sum this way:

def total_sale(self):
    total = Sale.objects.aggregate(TOTAL = Sum('amount'))['TOTAL']
    return total

Replace the 'amount' with the column name from your model you want to calculate the sum of and replace 'Sale' with your model name.

1 Comment

Please don't forget to import Sum: from django.db.models import Sum
3

You need to use aggregate() and Sum() to calculate the sum of price column as shown below. *The query with all() is equivalent to the query without all() as shown below:

from django.db.models import Sum

print(ItemPrice.objects.all().aggregate(Sum('price')))
print(ItemPrice.objects.aggregate(Sum('price')))

Then, these dictionaries below are outputted on console:

{'price__sum': Decimal('150.00')}
{'price__sum': Decimal('150.00')}

And, you can change the default key price__sum to priceSum for price column as shown below:

from django.db.models import Sum
                                        # ↓ Here
print(ItemPrice.objects.all().aggregate(priceSum=Sum('price')))
print(ItemPrice.objects.aggregate(priceSum=Sum('price')))
                                  # ↑ Here

Then, the default key is changed as shown below:

{'priceSum': Decimal('150.00')}
{'priceSum': Decimal('150.00')}

Comments

0

You can also make it simple

from django.db.models import Sum
product_total= Product.objects.aggregate(price=Sum('price'))['price'] or 0

which will give you just the amount. Eg: 4379 so the price is from your database column

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.