Django аннотирует исключение с помощью Case & When (Условное выражение) - PullRequest
2 голосов
/ 25 мая 2019

Я использую Django 2.2

При создании запроса я хочу подсчитать связанную модель, основываясь на нескольких условиях, таких как

    queryset = self.model.objects.filter(user=self.request.user).annotate(
        count_videos=Count('video'),
        count_completed=Count(
            Case(
                When(video__status__in=Video.STATUS_LIST_COMPLETED)
            )
        ),
        count_failed=Count(
            Case(
                When(video__status__in=Video.STATUS_LIST_FAILED)
            )
        ),
        count_pending=Count(
            Case(
                When(
                    video__status__not_in=Video.STATUS_LIST_PENDING_EXCLUDE
                )
            )
        )
    )

Здесь 3 счета работают, но в последнем счете count_pending я должен считать против exlude(). подсчитать количество записей, исключая переданный список.

Как я могу использовать exclude с приведенным выше утверждением?

1 Ответ

2 голосов
/ 25 мая 2019

Мы можем отменить значение, которое мы передаем параметру filter= [Django-doc] :

from django.db.models import Count, Q

queryset = self.model.objects.filter(user=self.request.user).annotate(
    count_videos=Count('video'),
    count_completed=Count(
        'video',
        filter=Q(video__status__in=STATUS_LIST_COMPLETED)
    ),
    count_failed=Count(
        'video',
        filter=Q(video__status__in=Video.STATUS_LIST_FAILED)
    ),
    count_pending=Count(
        'video',
        <b>filter=~Q(video__status__in=Video.STATUS_LIST_PENDING_EXCLUDE)</b>
    )
)

Это приведет к следующему запросу:

SELECT model.*,
    <b>COUNT(</b>
        CASE WHEN NOT video.status IN <i>STATUS_LIST_PENDING_EXCLUDE</i>
                  AND video.status IS NOT NULL
        THEN video.id
        ELSE NULL END
    ) <b>AS count_pending</b>
FROM model
LEFT OUTER JOIN video ON model.id = video.model_id
GROUP BY model.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...