Reputation: 3749
How to sum price group by month?
I try.
import itertools
qs = Contract.objects.values('created', 'proposal__price')
grouped = itertools.groupby(qs, lambda d: d.get('created').strftime('%Y-%m'))
data = [{'month': month, 'quant': sum(list(this_day))} for month, this_day in grouped]
print(data)
But result is no expected.
I need this similar result
[{'month': '2016-04', 'quant': 8650}, {'month': '2016-05', 'quant': 9050}]
Upvotes: 2
Views: 907
Reputation: 3749
My code adapted from @C14L.
import itertools
# from .models import Contract
c = Contract.objects.all().values('created', 'proposal__price')
gr = itertools.groupby(c, lambda d: d.get('created').strftime('%Y-%m'))
dt = [{'month': month, 'quant': sum([x['proposal__price'] for x in quant])} for month, quant in gr]
dt
Thanks.
Upvotes: 0
Reputation: 7616
Start by extracting the month and all your values
from django.db import connection
select = {'month': connection.ops.date_trunc_sql('month', 'created')}
qs = Contract.objects.extra(select=select).values('month').annotate(my_total=Sum('proposal__price'))
Now we can use a function to group by dict keys like so:
from itertools import groupby
from operator import attrgetter
get_y = attrgetter('month')
from collections import defaultdict, Counter
def solve(dataset, group_by_key, sum_value_keys):
dic = defaultdict(Counter)
for item in dataset:
key = item[group_by_key]
vals = {k:item[k] for k in sum_value_keys}
dic[key].update(vals)
return dic
Apply it to your queryset's newly annotated my_total
, grouped by month
:
solved = solve(qs, 'month', ['my_total'])
And you'll have grouped sums by month (month being a datetime object you can change manipulate to meet your needs):
for i in solved: print(i, ":", solved[i]['my_total'])
>>> datetime.datetime(2015, 9, 1, 0, 0, tzinfo=<UTC>) : 67614.23
>>> datetime.datetime(2015, 1, 1, 0, 0, tzinfo=<UTC>) : 54792.39
Now you can extract those values :)
Upvotes: 0
Reputation: 12548
Your this_day
inside sum(list(this_day))
is a dict
, so you need to build a list with a list comprehension. Example
>>> import itertools
>>> from django.contrib.auth.models import User
>>> li = User.objects.all().values('date_joined', 'username')
>>> gr = itertools.groupby(li, lambda d: d.get('date_joined').strftime('%Y-%m'))
>>> dt = [{'m': m, 'q': sum([len(x['username']) for x in q])} for m, q in gr]
>>> dt
[{'m': '2005-06', 'q': 11}, {'m': '2006-10', 'q': 22},
{'m': '2005-06', 'q': 179}, {'m': '2006-08', 'q': 10},
{'m': '2006-09', 'q': 30}, {'m': '2005-06', 'q': 74}, ... ]
Or, for your code, probably something like this
data = [{'month': month, 'quant': sum([x['proposal__price'] for x in this_day])}
for month, this_day in grouped]
Upvotes: 1