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!
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You’re probably looking for aggregate
from django.db.models import Sum
ItemPrice.objects.aggregate(Sum('price'))
# returns {'price__sum': 1000} for example
Method 2
Use .aggregate(Sum('column'))['column__sum'] reefer my example below
sum = Sale.objects.filter(type='Flour').aggregate(Sum('column'))['column__sum']
Method 3
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')}
Method 4
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.
Method 5
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))
Method 6
YOU COULD ALSO GET THE SUM BY 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.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0