Как группировать и агрегировать условно в Django ORM - PullRequest
1 голос
/ 25 апреля 2019

У меня есть запрос Django, чтобы получить среднее количество рабочих часов в день на одного сотрудника (может быть несколько рабочих журналов в день).Я хочу разделить их на рабочие дни и выходные.

Это рабочий журнал Модель:

class Worklog(models.Model):
    worker = models.ForeignKey(Person, on_delete=models.CASCADE)
    day = models.DateField(null=False, blank=False)
    effort = models.FloatField()
    comment = models.TextField(null=True)
    project = models.ForeignKey(Project, on_delete=models.CASCADE)

Я пробовал следующее:

    qs = Worklog.objects.filter(
                day__range=[start,end]
            ).values(
                'worker__fullname'

            ).annotate(
                weekday=Case(
                    When(Q(day__week_day=1) | Q(day__week_day=7), then=1),
                    default=0,
                    output_field=IntegerField(),
                )
            ).values(
                'worker__fullname'
            ).annotate(
                weekdayAvg=Case(
                    When(Q(weekday=0), then=Cast(
                    Sum('effort')/Count('day', distinct=True)/60/60, FloatField()
                )),
                    default=0,
                    output_field=FloatField(),
                ),
                weekendAvg=Case(
                    When(Q(weekday=1), then=Cast(
                    Sum('effort')/Count('day', distinct=True)/60/60, FloatField()
                )),
                    default=0,
                    output_field=FloatField(),
                )
            ).order_by('worker__fullname')

, что даетмне результат

     weekdayAvg  weekendAvg                        worker__fullname
0      9.125000        0.00                        Klaus
1      0.000000       11.00                        Klaus
2      6.977273        0.00                        Peter
3      7.827586        0.00                        Carl
4      0.000000       13.00                        Carl
5      8.169643        0.00                        Chris
6      0.000000        2.25                        Chris

Тем не менее, ожидаемый результат будет больше похож на:

     weekdayAvg  weekendAvg                        worker__fullname
0      9.125000        11.00                       Klaus
1      6.977273        0.00                        Peter
2      7.827586        13.00                       Carl
3      8.169643        2.25                        Chris

Любые идеи, как этого добиться?

Также я рад, что некоторыеупрощение моего запроса.Спасибо!

1 Ответ

0 голосов
/ 26 апреля 2019

Мне удалось не получить это сам.Подвиг, которого я раньше не знал, заключается в использовании параметра filter= в функциях агрегирования (Sum, Count и т.None (согласно этой записи)

...