Django在自定义ManyToMany字段上聚合的奇怪行为

时间:2018-06-26 19:14:41

标签: django database django-aggregation

我在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进行了比较。是否记录在某处?我什么都找不到。

1 个答案:

答案 0 :(得分:-1)

编写此代码时:

Task.objects.get(id=1)

您将获得Task实例,并且在Task模型中似乎有一个名为'annotate'且带有'number_solved'参数的方法。在某些查询集方法之后,您将无法进行任何注释:获取,计数,聚合,最后,首先存在,并且可能还会更多。此方法不返回查询集。

如果您想查看查询并进行比较。

您可以做两件事:

  1. print(Contest.objects.all()。query)#返回原始查询到数据库
  2. 安装django-extensions并使用此命令添加shell:

    ~# python manage.py shell_plus --print-sql  
    

如果您看到该查询,则可以对其进行比较并自己解决该问题