Django的注释方法和聚合方法之间的区别?


Answers:


186

我将重点放在示例查询上,而不是您在文档中的引用。Aggregate计算整个查询集的值。Annotate计算查询集中每个项目的汇总值。

聚合

>>> Book.objects.aggregate(average_price=Avg('price'))
{'average_price': 34.35}

返回包含查询集中所有书籍的平均价格的字典。

注解

>>> q = Book.objects.annotate(num_authors=Count('authors'))
>>> q[0].num_authors
2
>>> q[1].num_authors
1

q 是书籍的查询集,但每本书都注明了作者人数。


我是否.annotate()仅在qs上就不会打到db,而是打到了q[0].num_authors?我认为aggregate必须总是打db,因为它是一个terminal子句?
alias51

@ alias51与原始问题确实相关,因此我认为对八岁的问题的评论不是最好的提问地点。如果要检查查询何时运行,则可以检查connection.queries。提示:检查是否book = q[0]是导致查询的是“ book.num_authors”。
阿拉斯代尔

21

那是主要的区别,但是聚合也比注解在更大的范围内起作用。注释与查询集中的各个项目固有地相关。如果Count在多对多字段上运行注释,则将为查询集的每个成员获得单独的计数(作为添加的属性)。但是,如果要对聚合执行相同的操作,它将尝试计算查询集每个成员上的每个关系,甚至重复,并将其仅作为一个值返回。


我是否.annotate()仅在qs上不会打到db而是调用诸如dos这样的注释结果q[0].num_authors是否正确?我认为aggregate必须总是打db,因为它是一个terminal子句?
alias51

21

聚合 聚合在整个QuerySet上生成结果(摘要)值。汇总操作行集以从行集中获取单个值(例如,行集中所有价格的总和)。聚合应用于整个QuerySet,并在整个QuerySet上生成结果(摘要)值。

型号中:

class Books(models.Model):
    name = models.CharField(max_length=100)
    pages = models.IntegerField()
    price = models.DecimalField(max_digits=5, decimal_places=3)

在Shell中:

>>> Books.objects.all().aggregate(Avg('price'))
# Above code will give the Average of the price Column 
>>> {'price__avg': 34.35}

Annotate Annotate为QuerySet中的每个对象生成一个独立的摘要(可以说它迭代QuerySet中的每个对象并应用操作)

型号中:

class Video(models.Model):
    name = models.CharField(max_length=52, verbose_name='Name')
    video = models.FileField(upload_to=document_path, verbose_name='Upload 
               video')
    created_by = models.ForeignKey(User, verbose_name='Created by', 
                       related_name="create_%(class)s")
    user_likes = models.ManyToManyField(UserProfile, null=True, 
                  blank=True, help_text='User can like once', 
                         verbose_name='Like by')

在视图中:

videos = Video.objects.values('id', 'name','video').annotate(Count('user_likes',distinct=True)

在观看时,它将计算每个视频的点赞次数


为什么distinct=True在最后一个示例中需要?
Yuriy Leonov

@ YuriyLeonovdistant = True,用于对不同的值执行操作。它与当前提出的问题无关。抱歉,我实际上在我的代码上使用过。
Vinay Kumar,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.