我在Django的ManyToMany
字段上遇到了一些意外的(对我而言)聚合行为。
我有以下架构:
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
然后我有一个任务和两个竞赛,与该任务相关。如果我尝试对ContestTaskRelationship
个这样的模型进行注释(假设contest
是竞赛之一)
task = contest.tasks.annotate(number_solved=Count('contesttaskrelationship')).first()
我得到task.number_solved == 1
,但是当我这样尝试时:
task = Task.objects.filter(id=1).annotate(number_solved=Count('contesttaskrelationship')).first()
我得到了预期的结果task.number_solved == 2
。这是为什么?是不是同一对象和同一字段?
UPD :我发现在第一个示例中向查询添加了附加条件,将contest_id
与相应比赛的id
进行了比较。是否记录在某处?我什么都找不到。
答案 0 :(得分:-1)
编写此代码时:
Task.objects.get(id=1)
您将获得Task实例,并且在Task模型中似乎有一个名为'annotate'且带有'number_solved'参数的方法。在某些查询集方法之后,您将无法进行任何注释:获取,计数,聚合,最后,首先存在,并且可能还会更多。此方法不返回查询集。
如果您想查看查询并进行比较。
您可以做两件事:
安装django-extensions并使用此命令添加shell:
~# python manage.py shell_plus --print-sql
如果您看到该查询,则可以对其进行比较并自己解决该问题