I've encountered some unexpected (for me) behavior of aggregation over ManyToMany
field in django.
I have the following schema:
class ContestTaskRelationship(models.Model):
contest = models.ForeignKey('Contest', on_delete=models.CASCADE)
task = models.ForeignKey('Task', on_delete=models.CASCADE)
solved = models.ManyToManyField('User', related_name='contests_tasks_solved', blank=True)
cost = models.IntegerField(default=0)
class Contest(models.Model):
tasks = models.ManyToManyField('Task',
related_name='contests',
blank=True,
through='ContestTaskRelationship')
class Task(models.Model):
pass
Then I have one task and two contests, connected to that task. If I try to annotate count of ContestTaskRelationship
models like that (assuming contest
is one of the contests):
task = contest.tasks.annotate(number_solved=Count('contesttaskrelationship')).first()
I get task.number_solved == 1
, but when I try like that:
task = Task.objects.filter(id=1).annotate(number_solved=Count('contesttaskrelationship')).first()
I get the expected result task.number_solved == 2
. Why is that? Isn't it the same object and the same field?
UPD: I found out that in the first example additional condition is added to query, the contest_id
is compared to the id
of corresponding contest. Is it documented somewhere? I couldn't find anything.