0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

知ってる?Django Rest FrameworkでDBデータを加工して表示する方法

Posted at

はじめに

 初心者ながらバックエンドにDjango REST frameworkを使い、webアプリを作っています。データ一覧のapi表示は出来たのですが、そのデータをごちゃごちゃ計算して表示する方法に中々到達出来なかったので備忘録として残します。初学者なので、ご指摘あれば教えて頂けると嬉しいです。

やりたいこと

 以下のようなデータにおいて、datehourをそれぞれ合計し、表示させたいとします。

    {
        "id": 1
        "date": 1
        "hour": 2
    },
    {
        "id": 2
        "date": 2
        "hour": 3
    }

 APIで表示させたい内容は以下のようなものです。

    {
        "sum_date": 3
        "sum_hour": 5
    }

結論

 関数ベースビューを用いて実現します。まず結論となるプログラムです。

views.py
from django.db.models import Sum
from django.db.models.functions import Coalesce
from rest_framework.decorators import api_view
from rest_framework.response import Response

from .models import Data


@api_view(["GET"])
def get_summary_data(request):
    summary_dict = Data.objects.aggregate(
        sum_input_date=Coalesce(Sum("date"), 0), sum_input_hour=Coalesce(Sum("hour"), 0)
    )
    return Response(summary_dict)

@api_viewとは

 Httpメソッドを受け取り、それに応じてシリアライズされたデータをAPIに表示できるデコレータです。デコレータとは、関数を受け取り、関数を返す関数です。デコレータについてはとてもわかりやすい記事がありますので、詳しく知りたい方はぜひ。

 デフォルトはGETメソッドのみを受け取り、それ以外は405 Method Not Allowedを返します。他のメソッドを許可したい場合は、次の例のように@api_viewの引数にメソッドを追加します。

@api_view(['GET', 'POST'])
def hello_world(request):
    if request.method == 'POST':
        return Response({"message": "Got some data!", "data": request.data})
    return Response({"message": "Hello, world!"})

aggregateでデータを加工する

    summary_dict = Data.objects.aggregate(
        sum_input_date=Coalesce(Sum("date"), 0), sum_input_hour=Coalesce(Sum("hour"), 0)
    )

 データの加工は、aggregateで行います。データベースから受け取ったクエリセットを加工し、dictで返します。引数を設定することでキーが生成されるので、上記例だと、sum_input_datesum_input_hourというキーが作られます。

 Sumは、django.db.modelsからimportしたもので、データベース上のカラムを合計してくれます。

 Coalesceは、引数に取ったもののうち、nullでない最初のものを返すデータベース関数です。データが一つも入ってない場合に0を返し、エラーを回避しています。

勘違いしていたこと

 最初は、annotateが使えると思って必死に調べてましたが、各データに対しての集計ができるのがannotateなので今回は使えません。使い方を工夫すればできると思って固執してしまったのが良くありませんでした。

おわりに

 振り返れば簡単な内容ですね。3日もかかってしまいました…。でも、aggregateannotateの違いが、使い方も含め明確になったので結果オーライですかね!

参考記事

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?