我有这样的模型:
CLASS_TYPE = ( ("A","A Class"), ("B", "B Class") , ("C", "C Class") , ("D", "D Class") )
class Student(models.Model):
systemId = models.CharField(max_length=15, unique=True )
studentNo = models.CharField(max_length=15, unique=True )
country = models.CharField(max_length=50)
clasType = models.CharField(max_length=2, choices=CLASS_TYPE )
recordDate = models.DateField()
...
并且有很多记录。
我很有意思只有两个字段“country”和“classType”。 根据国家和总和,我想计算所有班级类型。
我想从list
模型中获取这个字典的Student
:
[ { "country":"USA" , "A" : Count_Of_A_Class_in_USA , "B" : Count_Of_B_Class_in_USA , "C" : countCinUSA , "D": count_D_in_USA , "Total" : total_students_in_USA } , {"Country":"England" , "A" : A_in_England ...., "C":C_in_England... , "Total" : students_in_England } ]
我怎么能得到这个?
我们可以首先根据country和per 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
的CLASS_TYPE
数量。