自動化無しに生活無し

WEBとかAIとかLinux関係をひたすら書く備忘録系ブログ

Djangoで複数の外部キーに対応したフィールドの個数をカウントする【annotate(Count)+DISTINCT】

thumbnail

【Django】外部キーに対応したデータの個数をカウントして表示【リプライ・コメント数の表示に有効】【annotate+Count】から

annotateで外部キーで繋がっているコメント数をカウントしてフィールドを追加するには下記のようにすれば良い。

from django.db.models import Count
Video.objects.annotate( num_comments=Count("videocomment") ).all().order_by("-dt")

Countの第一引数に外部キーで繋がっているモデルクラスの小文字を文字列型で指定する。

しかし、マイリスト数、良いねの数など複数の外部キーで繋がっている数をカウントしてフィールドを追加する場合、下記では失敗する。

from django.db.models import Count
Video.objects.annotate( num_comments    = Count("videocomment"),
                        num_mylists     = Count("mylist")
                        ).all().order_by("-dt")

カウントが重複されてしまうため、マイリスト等の値がおかしくなる。

そこで、第二引数にdistinct=Trueをセットする。これで重複は除外した上でカウントされ、正しい数値が表示される。

from django.db.models import Count
Video.objects.annotate( num_comments    = Count("videocomment", distinct=True),
                        num_mylists     = Count("mylist", distinct=True)
                        ).all().order_by("-dt")

結論

これで、検索時にコンテンツに繋がっているデータをカウントして表示させることが容易になった。

もっとも、カスタムテンプレートタグを使えばできなくもないが。

参照元

https://stackoverflow.com/questions/13145254/django-annotate-count-with-a-distinct-field

https://docs.djangoproject.com/en/3.2/topics/db/aggregation/#combining-multiple-aggregations

スポンサーリンク

シェアボタン

Twitter LINEで送る Facebook はてなブログ