Вы можете .annotate(..)
бойцов с этой метрикой качества, а затем фильтровать с заданным диапазоном, например:
from django.db.models import Count, ExpressionWrapper, FloatField
Fighter.objects.annotate(
<b>quality=</b>ExpressionWrapper(
<b>Count('wins', distinct=True)/Count('views', distinct=True)</b>,
output_field=FloatField()
)
).filter(
<b>quality__range=(0.5, 0.8)</b>
)
Необходимо distinct=True
, так как в противном случае качество всегда 1
: действительно, так как мы делаем два СОЕДИНЕНИЯ и подсчитываем id
с View
с и id
с Win
с, но эти цифры всегда совпадают.
Таким образом, quality__range=(0.5, 0.8)
будет фильтровать аннотацию quality
с помощью поиска __range
с 0.5
нижней границей и 0.8
верхней границей (оба включительно).
ExpressionWrapper(..., outputField=FloatField())
необходим для того, чтобы Django понимал, что quality
- это число с плавающей точкой, в противном случае он преобразует 0.5
и 0.8
в int
и, таким образом, проверяет значения между 0
и 0
.