I am trying to find the number of students enrolled by teacher. The code below produces the result I want. However, the code seems to be inefficiently long. I tried to simplify the code by using a "for" functiib, but couldn't solve it, so I posted a question to the experts for help.
The number registered in SPECIAL CLASS must be obtained separately.
The register condition is student with 1 entered in the day field.
monthly_kwargs = {
'jan': Count('student_id', filter=Q(register_date__gte='2022-01-01', register_date__lte='2022-01-31')),
'feb': Count('student_id', filter=Q(register_date__gte='2022-02-01', register_date__lte='2022-02-28')),
'mar': Count('student_id', filter=Q(register_date__gte='2022-03-01', register_date__lte='2022-03-31')),
'apr': Count('student_id', filter=Q(register_date__gte='2022-04-01', register_date__lte='2022-04-30')),
'may': Count('student_id', filter=Q(register_date__gte='2022-05-01', register_date__lte='2022-05-31')),
'jun': Count('student_id', filter=Q(register_date__gte='2022-06-01', register_date__lte='2022-06-30')),
'jul': Count('student_id', filter=Q(register_date__gte='2022-07-01', register_date__lte='2022-07-31')),
'aug': Count('student_id', filter=Q(register_date__gte='2022-08-01', register_date__lte='2022-08-31')),
'sept': Count('student_id', filter=Q(register_date__gte='2022-09-01', register_date__lte='2022-09-30')),
'oct': Count('student_id', filter=Q(register_date__gte='2022-10-01', register_date__lte='2022-10-31')),
'nov': Count('student_id', filter=Q(register_date__gte='2022-11-01', register_date__lte='2022-11-30')),
'dec': Count('student_id', filter=Q(register_date__gte='2022-12-01', register_date__lte='2022-12-31')),
'total': Count('student_id', filter=Q(register_date__year=today.year)),
'SPECIAL_jan': Count('student_id', filter=Q(register_date__gte='2022-01-01', register_date__lte='2022-01-31', student__class__id__in=SPECIAL)),
'SPECIAL_feb': Count('student_id', filter=Q(register_date__gte='2022-02-01', register_date__lte='2022-02-28', student__class__id__in=SPECIAL)),
'SPECIAL_mar': Count('student_id', filter=Q(register_date__gte='2022-03-01', register_date__lte='2022-03-31', student__class__id__in=SPECIAL)),
'SPECIAL_apr': Count('student_id', filter=Q(register_date__gte='2022-04-01', register_date__lte='2022-04-30', student__class__id__in=SPECIAL)),
'SPECIAL_may': Count('student_id', filter=Q(register_date__gte='2022-05-01', register_date__lte='2022-05-31', student__class__id__in=SPECIAL)),
'SPECIAL_jun': Count('student_id', filter=Q(register_date__gte='2022-06-01', register_date__lte='2022-06-30', student__class__id__in=SPECIAL)),
'SPECIAL_jul': Count('student_id', filter=Q(register_date__gte='2022-07-01', register_date__lte='2022-07-31', student__class__id__in=SPECIAL)),
'SPECIAL_aug': Count('student_id', filter=Q(register_date__gte='2022-08-01', register_date__lte='2022-08-31', student__class__id__in=SPECIAL)),
'SPECIAL_sept': Count('student_id', filter=Q(register_date__gte='2022-09-01', register_date__lte='2022-09-30', student__class__id__in=SPECIAL)),
'SPECIAL_oct': Count('student_id', filter=Q(register_date__gte='2022-10-01', register_date__lte='2022-10-31', student__class__id__in=SPECIAL)),
'SPECIAL_nov': Count('student_id', filter=Q(register_date__gte='2022-11-01', register_date__lte='2022-11-30', student__class__id__in=SPECIAL)),
'SPECIAL_dec': Count('student_id', filter=Q(register_date__gte='2022-12-01', register_date__lte='2022-12-31', student__class__id__in=SPECIAL)),
'SPECIAL_total': Count('student_id', filter=Q(register_date__year=today.year, student__class__id__in=SPECIAL))
}
value_list_args = ['teacher__first_name', 'jan', 'feb', 'mar', 'apr', 'may', 'jun', 'jul', 'aug', 'sept', 'oct', 'nov', 'dec', 'total',
'SPECIAL_jan', 'SPECIA_feb', 'SPECIA_mar', 'SPECIA_apr', 'SPECIA_may', 'SPECIA_jun', 'SPECIA_jul', 'SPECIA_aug', 'SPECIA_sept', 'SPECIA_oct', 'SPECIA_nov', 'SPECIA_dec', 'SPECIA_total']
monthly_enroll = DayCheck.objects.filter(Q(day='1', register_date__year=today.year)) \
.values('teacher__first_name').distinct() \
.order_by('teacher__first_name') \
.annotate(**monthly_kwargs) \
.values_list(*value_list_args) \
.order_by('teacher__first_name')
monthly_enroll_list = [];
for i in monthly_enroll:
inside_list = []
for j in i:
inside_list.append(j)
monthly_enroll_list.append(inside_list[0:27])
CodePudding user response:
This code seems like it may have been adapted from JavaScript, given the number of dot operators dangling off of DayCheck
. Nevertheless, here are some ideas:
- If the order of items in
monthly_kwargs
doesn't matter, then you can loop over months to save some lines (though I'm not sure it's actually clearer or easier to read that way. - The
monthly_enroll_list
can be turned into a very concise list comprehension, so that's good!
from datetime import datetime, timedelta
monthly_kwargs = {}
for i in range(1, 13):
gte = datetime(2022, i, 1)
lte = datetime(2022 i // 12, (i 1) % 12, 1) - timedelta(1)
mo = f'{gte:%b}'.lower()
monthly_kwargs[mo] = Count('student_id', filter=Q(
register_date__gte=f'{gte:%Y-%m-%d}',
register_date__lte=f'{lte:%Y-%m-%d}'
))
monthly_kwargs['SPECTIAL_' mo] = Count('student_id', filter=Q(
register_date__gte=f'{gte:%Y-%m-%d}',
register_date__lte=f'{lte:%Y-%m-%d}', student__class__id__in=SPECIAL
))
monthly_kwargs['total'] = Count('student_id', filter=Q(
register_date__year=today.year
))
monthly_kwargs['SPECIAL_total'] = Count('student_id', filter=Q(
register_date__year=today.year, student__class__id__in=SPECIAL
))
value_list_args = [
'teacher__first_name', 'jan', 'feb', 'mar', 'apr', 'may',
'jun', 'jul', 'aug', 'sept', 'oct', 'nov', 'dec', 'total',
'SPECIAL_jan', 'SPECIA_feb', 'SPECIA_mar', 'SPECIA_apr', 'SPECIA_may',
'SPECIA_jun', 'SPECIA_jul', 'SPECIA_aug', 'SPECIA_sept', 'SPECIA_oct',
'SPECIA_nov', 'SPECIA_dec', 'SPECIA_total'
]
monthly_enroll = DayCheck.objects\
.filter(Q(day='1', register_date__year=today.year))\
.values('teacher__first_name').distinct().order_by('teacher__first_name')\
.annotate(**monthly_kwargs).values_list(*value_list_args)\
.order_by('teacher__first_name')
monthly_enroll_list = [list(i)[0:27] for i in monthly_enroll]