Я пытаюсь отфильтровать мою модель с помощью агрегатной функции.
У меня есть модель A и модель B с внешним ключом на модели A.
annotate_pool = queryset.annotate(nb_bets=Count('bets')).all()
for obj in annotate_pool:
bets_obj = obj.bets.all()
bets_length = len(bets_obj)
print(obj.nb_bets, bets_length)
И аннотация не дает мне тот же результат, что и длина функции.
1 1
1 2
1 2
1 2
1 2
1 1
1 1
2 2
Вот мои модели:
class Pronostic(models.Model):
cote_total = models.FloatField(default=0.0)
trust = models.IntegerField()
mise_ratio = models.IntegerField(default=10)
safe = models.BooleanField(default=False)
class Bet(models.Model):
name = models.CharField(max_length=255)
match = models.ForeignKey('pronostics.Match', on_delete=models.CASCADE, related_name='bets')
cote = models.FloatField()
status = models.IntegerField(choices=STATUS, default=0)
pronostic = models.ForeignKey('pronostics.Pronostic', related_name='bets', on_delete=models.CASCADE)
len(bets_obj)
должен дать мне тот же результат, что и Count('bets')
.
Что здесь происходит? Почему Count
дает мне неправильный результат?
Заранее спасибо.
EDIT:
Я использую django-rest-framework и пытаюсь добавить пользовательский фильтр. ( см. Документ здесь ).
Ожидаемый результат:
obj.nb_bets
должно быть равно bets_length
. Поскольку я хочу отфильтровать свои модели следующим образом:
queryset.annotate(nb_bets=Count('bets')).filter(nb_bets__gte=2)
или
queryset.annotate(nb_bets=Count('bets')).filter(nb_bets__lte=2)
Вот запрос SQL, содержащийся в моем наборе запросов:
SELECT "pronostics_pronostic"."id",
"pronostics_pronostic"."cote_total",
"pronostics_pronostic"."trust",
"pronostics_pronostic"."mise_ratio",
"pronostics_pronostic"."safe"
FROM "pronostics_pronostic"
LEFT OUTER JOIN "pronostics_bet"
ON ("pronostics_pronostic"."id" = "pronostics_bet"."pronostic_id")
LEFT OUTER JOIN "pronostics_match"
ON ("pronostics_bet"."match_id" = "pronostics_match"."id")
WHERE ("pronostics_pronostic"."visible" = TRUE
AND "pronostics_pronostic"."safe" = TRUE)
ORDER BY "pronostics_match"."date" DESC
Если вам нужна дополнительная информация, дайте мне знать.