注释中的params为什么以及如何相互影响?

时间:2018-01-09 22:02:16

标签: python django aggregate-functions

我一直在阅读https://docs.djangoproject.com/en/1.11/topics/db/aggregation/,但我仍然遗漏了一些东西。

使用Django 1.11,说我有以下型号:

class School(models.Model):
    pass

class Classroom(models.Model):
    school = models.ForeignKey(School, on_delete=models.PROTECT)
    active = models.BooleanField()
    busy = models.BooleanField()

class Chalkboard(models.Model):
    classroom = models.ForeignKey(Classroom, on_delete=models.PROTECT)

class Whiteboard(models.Model):
    classroom = models.ForeignKey(Classroom, on_delete=models.PROTECT)

我创建了一所学校,有一个教室,有2个白板和2个黑板:

s = School()
s.save()

c = Classroom(school=s, active=True, busy=False)
c.save()

Chalkboard(classroom=c).save()
Chalkboard(classroom=c).save()

Whiteboard(classroom=c).save()
Whiteboard(classroom=c).save()
Whiteboard(classroom=c).save()

我想要总结一下每所学校有多少个黑板,但是不是很忙。

q = School.objects.filter(
    Q(classroom__active=True) & Q(classroom__busy=False)
).annotate(
    chalkboard_count=Count('classroom__chalkboard'),
)

q[0].chalkboard_count
2                        # as expected

现在我想了解黑板和白板。

q = School.objects.filter(
    Q(classroom__active=True) & Q(classroom__busy=False)
).annotate(
    chalkboard_count=Count('classroom__chalkboard'),
    whiteboard_count=Count('classroom__whiteboard'), # added this line
)

q[0].chalkboard_count
6                        # expected 2
q[0].whiteboard_count
6                        # expected 3

如果我将调用链接到注释,我会得到相同的结果。

q = School.objects.filter(
    Q(classroom__active=True) & Q(classroom__busy=False)
).annotate(
    chalkboard_count=Count('classroom__chalkboard')
).annotate(
    whiteboard_count=Count('classroom__whiteboard')
)

q[0].chalkboard_count
6                        # expected 2
q[0].whiteboard_count
6                        # expected 3

一直以来,这些都是我所期待的

Chalkboard.objects.count()
2
Whiteboard.objects.count()
3

我在这里做错了什么?

1 个答案:

答案 0 :(得分:1)

从您发布的链接:

  

组合多个聚合

     

将多个聚合与annotate()组合将产生错误   结果因为使用了连接而不是子查询:   对于大多数聚合,没有办法避免这个问题,但是,   Count聚合有一个可能有用的独特参数:

Book.objects.annotate(
    Count('authors', distinct=True), 
    Count('store', distinct=True)
)