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

时间:2011-11-02 14:18:52

标签: django django-queryset

Django的QuerySet有两种方法,annotateaggregate。文档说:

  

与aggregate()不同,annotate()不是终结子句。 annotate()子句的输出是QuerySet。

它们之间还有其他区别吗?如果没有,那么为什么aggregate存在?

3 个答案:

答案 0 :(得分:145)

我会专注于示例查询而不是文档中的引用。 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是书籍的查询集,但每本书都注明了作者的数量。

答案 1 :(得分:18)

这是主要区别,但聚合也比注释更大。注释本质上与查询集中的各个项相关。如果对类似多对多字段的内容运行Count注释,则会为查询集的每个成员获取单独的计数(作为添加的属性)。但是,如果您对聚合执行相同的操作,它将尝试计算查询集的每个成员上的每个关系,即使是重复项,并将其作为一个值返回。

答案 2 :(得分:11)

<强>汇总 Aggregate在整个QuerySet上生成结果(摘要)值。 聚合操作在行集上以从行集中获取单个值。(例如,行集中所有价格的总和)。 Aggregate应用于整个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为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)

在视图中,它会计算每个视频的喜欢