Как оптимизировать код с помощью оператора for
Я пытаюсь найти количество студентов, зачисленных учителем. Приведенный ниже код дает нужный мне результат. Однако код кажется неэффективно длинным. Я попытался упростить код с помощью функции "for", но не смог решить эту проблему, поэтому я обратился за помощью к экспертам.
Номер, зарегистрированный в SPECIAL CLASS, должен быть получен отдельно.
Условием регистра является студент, если в поле день введена 1.
Этот код кажется адаптированным из JavaScript, учитывая количество точечных операторов, свисающих из DayCheck. Тем не менее, вот несколько идей:
- Если порядок элементов в
monthly_kwargsне имеет значения, то вы можете перебирать месяцы, чтобы сэкономить несколько строк (хотя я не уверен, что это действительно чище или легче для чтения таким образом. -
monthly_enroll_listможно превратить в очень сжатое понимание списка, так что это хорошо!
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]