2018/07/24
Django モデル クエリセットデータの個数や最高値、平均値を取得してみよう
アグリゲーション(Aggregation)ってなに?
アグリゲーションとは、データベースに格納されているデータの個数、平均値、最高値などを調べてくれる機能のことです。Aggregationは「集計」を意味します。
データベースの中から、欲しい情報を取得するときに重宝します。
今回は以下のような例のモデルを使います。値段や評価フィールドを持つBookオブジェクトがあり、BookオブジェクトはAuthorオブジェクトと紐づいています。
models.py
from django.db import models
class Author(models.Model):
name = models.CharField('名前', max_length=190)
def __str__(self):
return self.name
class Book(models.Model):
author = models.ForeignKey(Author, on_delete=models.CASCADE)
title = models.CharField('タイトル', max_length=190)
price = models.IntegerField('値段')
rating = models.FloatField('評価')
def __str__(self):
return self.title
上のモデルから、適当にいくつかのBookインスタンスを作成しました。(下図)このデータを使って、集計処理を行ってみたいと思います。
オブジェクトの数を数える(Count)
Bookオブジェクトの数を調べる
Book.objects.all().count()
# 6
最高値を抽出する(Max)
1番高い値段を調べる
from django.db.models import Max
Book.objects.all().aggregate(Max('price'))
# {'price__max': 1500}
平均値を算出する(Avg)
川端康成の評価平均値を求める
from django.db.models import Avg
Book.objects.filter(author__name='川端康成').aggregate(Avg('rating'))
# {'rating__avg': 3.0}
フィールドごとに集計する(annotate)
annotateは、新たなフィールドを生成してくれるイメージです。
下の例では、book__count、published_booksというフィールドを生成し、各Authorと紐づいているBookオブジェクトの数がわかるようになっています。
Authorが出版したBookの数を調べる
from django.db.models import Count
# クエリセットを生成
authors = Author.objects.all().annotate(Count('book'))
# <QuerySet [<Author: 川端康成>, <Author: 芥川龍之介>, <Author: 太宰治>]>
# 上で作成したクエリセットのインスタンスは、book__countというプロパティを持つ
authors[0].book__count
# 3
# 下記のように、フィールド名を指定することもできる
authors = Author.objects.all().annotate(published_books=Count('book'))
authors[0].published_books
# 3
保有するオブジェクト数順に並べる(annotate)
annotateで生成された、フィールドを使って並び替えができる。
出版したBookの数が多い順にAuthorを並べる
from django.db.models import Count
authors = Author.objects.all().annotate(Count('book')).order_by('-book__count')
# <QuerySet [<Author: 川端康成>, <Author: 芥川龍之介>, <Author: 太宰治> ]>
上の例では、出版した本が多い順にAuthorを並び替えたクエリセットを作成しています。
もっと詳しい情報が知りたい場合は こちらから。