Совокупность Django Count только True значения

Я использую агрегат, чтобы получить количество столбцов логических значений. Я хочу количество истинных значений.

КОД ДЖАНГО:

count = Model.objects.filter(id=pk).aggregate(bool_col=Count('my_bool_col')

Это возвращает количество всех строк.

SQL-запрос ДОЛЖЕН БЫТЬ:

SELECT count(CASE WHEN my_bool_col THEN 1 ELSE null END) FROM <table_name>

Вот мой фактический код:

stats = Team.objects.filter(id=team.id).aggregate(
    goals=Sum('statistics__goals'),
    assists=Sum('statistics__assists'),
    min_penalty=Sum('statistics__minutes_of_penalty'),
    balance=Sum('statistics__balance'),
    gwg=Count('statistics__gwg'),
    gk_goals_avg=Sum('statistics__gk_goals_avg'),
    gk_shutout=Count('statistics__gk_shutout'),
    points=Sum('statistics__points'),
)

Благодаря предложению Питера ДеГлоппера использовать django-aggregate-if

Вот решение:

from django.db.models import Sum
from django.db.models import Q
from aggregate_if import Count

stats = Team.objects.filter(id=team.id).aggregate(
    goals=Sum('statistics__goals'),
    assists=Sum('statistics__assists'),
    balance=Sum('statistics__balance'),
    min_penalty=Sum('statistics__minutes_of_penalty'),
    gwg=Count('statistics__gwg', only=Q(statistics__gwg=True)),
    gk_goals_avg=Sum('statistics__gk_goals_avg'),
    gk_shutout=Count('statistics__gk_shutout', only=Q(statistics__gk_shutout=True)),
    points=Sum('statistics__points'),
)

Ответы

Ответ 1

Обновление:

Начиная с Django 1.10 вы можете:

from django.db.models import Count, Case, When
query_set.aggregate(
    bool_col=Count(
        Case(When(my_bool_col=True, then=Value(1)))
    )
)

Читайте о классах условных выражений

Старый ответ.

Похоже, что вы хотите сделать, это что-то вроде "условного агрегирования". В настоящее время функции Aggregation не поддерживают поиск, например, filter или exclude: fieldname__lt, fieldname__gt,...

Таким образом, вы можете попробовать это:

Джанго-агрегированных если

Описание взято с официальной страницы.

Условные агрегаты для запросов Django, такие же, как известные SumIf и CountIf в Excel.

Вы также можете сначала аннотировать желаемое значение для каждой команды, я имею в виду подсчет для каждой команды суммы True в интересующей вас области. А затем выполните все агрегацию, которую вы хотите.

Ответ 3

Другое решение для графа Bool:

from django.db.models import Sum, IntegerField
from django.db.models.functions import Cast

Model.objects.filter(id=pk).annotate(bool_col=Sum(Cast('my_bool_col', IntegerField())))

Просто преобразуйте False в 0 и True в 1, а затем просто Sum