データベースのレコードをオブジェクトとして取得する際、データベースと直接クエリをやり取りするのは「クエリセットAPI」と呼ばれるものです。
テーブルを検索する際はモデルのモデルマネージャーを経由してクエリセットAPIのメソッドを呼び出します。
(引用元:現場で使えるDjangoの教科書)
クエリセットAPIのメソッドには
・get() 1件のオブジェクトを取得する
・all() レコード全件に対応するオブジェクトのリストを取得する
・filter() 検索条件を付けてオブジェクトのリストを取得する
など多数のメソッドが用意されています。
今回はannotate()メソッドについて説明します。
annotate()
annotateという動詞が「注釈を付ける」という意味を持つように、
annotate()メソッドは各オブジェクトに即席のカラムを追加するような役割をします。
親であるBlog(ブログ)モデルと、子であるEntry(投稿)モデルがあるとして、annotate()は以下のように使うことができます。
# Blogモデルにnumber_of_entries(投稿数)という名前で注釈を付ける。
# Count()という集計関数を使い、引数に逆参照先のモデル名を指定し、Blogオブジェクトと紐づくEntryオブジェクトの数を集計します。
>>> q = Blog.objects.annotate(number_of_entries=Count('entry'))
# オブジェクト.注釈名とすることで、Blogオブジェクトと紐づくEntryオブジェクトの値を返すことができます。
>>> q[0].number_of_entries
42
またnumber_of_entriesのようなキーワードを付けず、下記のようにすることもできます。
# 注釈のキーワードを付けず、集計関数のみ。
>>> q = Blog.objects.annotate(Count('entry'))
# 逆参照先モデル名__countとすることで、前述と同様の結果が得られる。
>>> q[0].entry__count
42