web-dev-qa-db-ja.com

Djangoの注釈メソッドと集約メソッドの違いは?

DjangoのQuerySetには、annotateaggregateの2つのメソッドがあります。ドキュメントには次のように書かれています:

Aggregate()とは異なり、annotate()は終端句ではありません。 annotate()句の出力はQuerySetです。

それらの間に他の違いはありますか?そうでない場合、なぜaggregateが存在するのですか?

93

ドキュメントからの引用ではなく、クエリの例に焦点を当てます。 Aggregateは、全体クエリセットの値を計算します。 Annotateは、クエリセット内の各アイテムのサマリー値を計算します。

集計

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

クエリセット内のall本の平均価格を含む辞書を返します。

注釈

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

qは書籍のクエリセットですが、各書籍には著者数が注釈されています。

153
Alasdair

これが主な違いですが、集計は注釈よりも大規模に機能します。注釈は、本質的にクエリセット内の個々のアイテムに関連しています。多対多フィールドのようなものに対してCount注釈を実行すると、クエリセットの各メンバーに対して個別のカウントが(追加属性として)取得されます。ただし、集約で同じことを行うと、クエリセットのeveryメンバーのすべての関係、重複もカウントし、それを1つの値として返します。

18
Chris Pratt

Aggregate Aggregateは、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)

シェルで:

>>> 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)

ビューでは、各ビデオのいいねを数えます

11
Vinay Kumar