Разделение между двумя аннотациями

Я создаю эти две аннотации следующим образом:

cs = Champion.objects.all()

total_games = Match.objects.all().count()

cs = cs.annotate(
    picked_games=Count(
        expression='participants__match__id',
        filter=Q(participants__role='BOTTOM'),
        distinct=True
    ),
    total_games=Value(str(total_games), output_field=IntegerField())
)

И все в порядке до этого момента. Я получаю и picked_games и total_games с правильными результатами.

>>> cs.get(name='Jhin').picked_games
27544
>>> cs.get(name='Jhin').total_games
97410

Однако, если я попытаюсь разделить одно на другое:

cs = cs.annotate(
    pick_rate=ExpressionWrapper(
        expression=F('picked_games') / F('total_games'),
        output_field=FloatField()
    )
)

В результате получается 0:

>>> cs.get(name='Jhin').pick_rate
0.0

Я не понимаю, в чем здесь проблема...

Я могу получить результат, если разделить их внешне, так почему я не могу получить результат по другому столбцу для всего набора запросов?

>>> cs.get(name='Jhin').picked_games / cs.get(name='Jhin').total_games
0.28319474386613286

Вы должны привести числитель (или знаменатель) к float перед выполнением деления, иначе база данных PostgreSQL будет использовать целочисленное деление и, следовательно, усекать до нуля. Таким образом, вы можете работать с:

from django.db.models import Count, F, FloatField, Q
from django.db.models.functions import Cast

total_games = Match.objects.all().count()

Champion.objects.annotate(
    picked_games=Count(
        expression='participants__match__id',
        filter=Q(participants__role='BOTTOM'),
        distinct=True
    )
).annotate(
    pick_rate=Cast('picked_games', output_field=FloatField()) / total_games
)
Вернуться на верх