def getClassTypeMonthlyData(year=None, series=None, typeLimit=None):
<EOL>if not year:<EOL><INDENT>year = timezone.now().year<EOL><DEDENT>role_list = DanceRole.objects.distinct()<EOL>if series not in ['<STR_LIT>','<STR_LIT>'] and series not in [x.pluralName for x in role_list]:<EOL><INDENT>series = '<STR_LIT>'<EOL><DEDENT>when_all = {<EOL>'<STR_LIT>': False,<EOL>'<STR_LIT>': False,<EOL>}<EOL>annotations = {'<STR_LIT>': Sum(Case(When(Q(**when_all),then=<NUM_LIT:1>),output_field=FloatField()))}<EOL>for this_role in role_list:<EOL><INDENT>annotations[this_role.pluralName] = Sum(Case(When(Q(Q(**when_all) & Q(eventregistration__role=this_role)),then=<NUM_LIT:1>),output_field=FloatField()))<EOL><DEDENT>series_counts = Series.objects.filter(year=year).annotate(**annotations).annotate(studenthours=F('<STR_LIT>') * F('<STR_LIT>')).select_related('<STR_LIT>','<STR_LIT>')<EOL>dance_type_counts = [(dance_type,count) for dance_type,count in Counter([x.classDescription.danceTypeLevel for x in series_counts]).items()]<EOL>dance_type_counts.sort(key=lambda k: k[<NUM_LIT:1>],reverse=True)<EOL>if typeLimit:<EOL><INDENT>dance_types = [x[<NUM_LIT:0>] for x in dance_type_counts[:typeLimit]]<EOL><DEDENT>else:<EOL><INDENT>dance_types = [x[<NUM_LIT:0>] for x in dance_type_counts]<EOL><DEDENT>results = []<EOL>for month in range(<NUM_LIT:1>,<NUM_LIT>):<EOL><INDENT>this_month_result = {<EOL>'<STR_LIT>': month,<EOL>'<STR_LIT>': month_name[month],<EOL>}<EOL>for dance_type in dance_types:<EOL><INDENT>this_month_result[dance_type.__str__()] =series_counts.filter(classDescription__danceTypeLevel=dance_type,month=month).aggregate(Sum(series))['<STR_LIT>' % series]<EOL><DEDENT>if typeLimit:<EOL><INDENT>this_month_result['<STR_LIT>'] =series_counts.filter(month=month).exclude(classDescription__danceTypeLevel__in=dance_types).aggregate(Sum(series))['<STR_LIT>' % series]<EOL><DEDENT>results.append(this_month_result)<EOL><DEDENT>totals_result = {<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>'<STR_LIT>': '<STR_LIT>',<EOL>}<EOL>for dance_type in dance_types:<EOL><INDENT>totals_result[dance_type.__str__()] =series_counts.filter(classDescription__danceTypeLevel=dance_type).aggregate(Sum(series))['<STR_LIT>' % series]<EOL><DEDENT>if typeLimit:<EOL><INDENT>totals_result['<STR_LIT>'] =series_counts.exclude(classDescription__danceTypeLevel__in=dance_types).aggregate(Sum(series))['<STR_LIT>' % series]<EOL><DEDENT>results.append(totals_result)<EOL>return results<EOL>
To break out by class type and month simultaneously, get data for each
series and aggregate by class type.