6π
If you have that date model so you can fetch all b
s then group them by a
and calculate total amount. Code may look like this:
View:
from django.utils.itercompat import groupby
def view(request):
bs = B.objects.all().annotate(sum_of_c_val=Sum('c.val'))\
.select_related('a')
b_by_a = [
{
'grouper': key,
'list': list(val),
'total': sum([b.sum_of_c_val for b in val])
}
for key, val in
groupby(bs, lambda b: b.a)
]
return render_to_response('tmpl.html', {'b_by_a': b_by_a})
And template:
{% for b_group in b_by_a %}
{% for b in b_group.list %}
<tr>
<td>{{b_group.grouper.name}}</td>
<td>{{b.name}}</td>
<td>{{b.sum_of_c_val}}</td>
</tr>
{% endfor %}
<tr>
<td>{{b_group.grouper.name}}</td>
<td>Total</td>
<td>{{b_group.total}}</td>
</tr>
{% endfor %}
EDIT:
For compatible with Django 1.0 you have to replace annotate
call with extra
select or in-python amount calculation.
-
With subquery:
bs = B.objects.all().extra( select={ 'sum_of_c_val': 'SELECT SUM(app_c.val) FROM app_c WHERE app_c.b_id=app_b.id' }).select_related('a') #...
Where
app
β application name -
This in-python calculation:
bs = B.objects.all().select_related('a') for b in bs: b.sum_of_c_val = sum(map(int, b.c.all().values_list("val", flat=True))) #...
But it produces N additional queries (where
N = len(bs)
)
1π
Disclaimer: Iβm a Django beginner myself, but if Iβve understood its basic concepts right, then:
Given that the view you want is β as you say β just a view of the underlying data, then you should do the sorting and grouping in the view module. I donβt think you should mess with the model (which is just the data), nor with the template (which is just a layout of the view).
- [Django]-Django: How to keep track of a linear (yet flexible) project management workflow?
- [Django]-Save user with generated password with Django