Сначала мы можем сделать запрос, который для каждой страны и для clasType получает число Student
s:
qs = Student.objects.values('country', 'clasType').annotate(
n=Count('pk')
).order_by('country', 'clasType')
Теперь мы можем использовать itertools.groupby
[Python-doc] для группировки этих словарей в более компактные словари:
from itertools import groupby
from operator import itemgetter
data = [
{'country': c, ** { li['clasType']: li['n'] for li in l } }
for c, l in groupby(qs, itemgetter('country'))
]
Но нам все еще нужно сделать «исправления»: возможно, что в стране есть не все clasType
s, мы, вероятно, хотим добавить 0
s для них, и, кроме того, нам нужно вычислить общее количество. Мы можем сделать это с:
for subd in data:
total = 0
for ct, _ in CLASS_TYPE:
total += subd.setdefault(ct, 0)
subd['Total'] = total
Теперь data
содержит список словарей, каждый словарь имеет ключ 'country'
и 'Total'
, а для каждого ключа CLASS_TYPE
и число Student
s для этого CLASS_TYPE
.