DjangoにQuerySet
は2つのメソッドがannotate
ありaggregate
ます。ドキュメントは言う:
aggregate()とは異なり、annotate()は終了句ではありません。annotate()句の出力はQuerySetです。
それらの間に他の違いはありますか?そうでない場合、なぜaggregate
存在するのですか?
DjangoにQuerySet
は2つのメソッドがannotate
ありaggregate
ます。ドキュメントは言う:
aggregate()とは異なり、annotate()は終了句ではありません。annotate()句の出力はQuerySetです。
それらの間に他の違いはありますか?そうでない場合、なぜaggregate
存在するのですか?
回答:
ドキュメントからの引用よりも、クエリ例に焦点を当てます。クエリセット全体の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
は書籍のクエリセットですが、各書籍には作者の数で注釈が付けられています。
connection.queries
。ヒント:book = q[0]
クエリの原因はか `book.num_authors` かどうかを確認してください。
これが主な違いですが、集計はアノテーションよりも大規模に機能します。アノテーションは本質的にクエリセットの個々のアイテムに関連しています。Count
多対多フィールドのようなものに対して注釈を実行すると、クエリセットのメンバーごとに個別のカウントが(追加された属性として)取得されます。ただし、集計で同じことを行うと、クエリセットのすべてのメンバーのすべての関係をカウントしようとし、重複する場合でも、それを1つの値として返します。
.annotate()
はqsだけでdbにヒットしないことを訂正してq[0].num_authors
いますか?aggregate
ターミナル句なので、常にdbをヒットする必要があると思いますか?
Aggregate 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)
シェル:
>>> 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
最後の例でなぜ必要なのですか?
.annotate()
はqsだけでdbをヒットしないことを修正q[0].num_authors
しますが、呼び出しはヒットしますか?aggregate
ターミナル句なので、常にdbをヒットする必要があると思いますか?