Совокупный набор запросов для расчета процента всегда возвращает 0 - PullRequest
2 голосов
/ 03 февраля 2020

Я пытаюсь написать Django набор запросов, который агрегирует процент проверенных контрактов в нашей системе. Кажется, я не могу заставить его работать - я всегда получаю «0» за процент, хотя я знаю, что он должен быть ближе к 25%.

Мои текущие попытки следующие:

In[1]: Contract.objects.aggregate(
    total=Count('pk'),
    verified=Count('pk', filter=Q(verified_date__isnull=False)
)
Out[1]: {'total': 4000, 'verified': 1000}

In[2]: Contract.objects.aggregate(
    percentage=Count('pk', filter=Q(verified_date__isnull=False)) / Count('pk')
)
Out[2]: {'percentage': 0}

In[3]: Contract.objects.aggregate(
    percentage=Count('pk', filter=Q(verified_date__isnull=False), output_field=DecimalField()) / Count('pk', output_field=DecimalField())
)
Out[3]: {'percentage': Decimal('0')}

1 Ответ

1 голос
/ 03 февраля 2020

Вам нужно сделать десятичные значения перед их делением, просто умножьте на 1,0, чтобы убедиться в этом:

from django.db.models import ExpressionWrapper, Count, Value, DecimalField

Contract.objects.aggregate(perc=ExpressionWrapper(
    Count('pk', filter=Q(verified_date__isnull=False)) * Value(1.0) 
    / (Count('pk') * Value(1.0)), 
    output_field=DecimalField()))

Я использую ExpressionWrapper, чтобы иметь возможность установить параметр output_field на Само значение агрегации.

ОБНОВЛЕНИЕ: После рассмотрения этой проблемы на основе комментария о том, что приведение к output_field должно работать, я Выяснилось, что это также работает:

from django.db.models import Count, DecimalField
from django.db.models.functions import Cast

Contract.objects.aggregate(perc=
    Cast(
        Count('pk', filter=Q(verified_date__isnull=False)), 
        DecimalField(max_digits=30, decimal_places=4)
    ) 
    / Cast(
        Count('pk'), 
        DecimalField(max_digits=30, decimal_places=4)
    )
)

Упомянутая выше проблема объясняет, почему output_field не работает. Кажется, что это будет в будущем: -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...