HOWTO · Django

Django で JSON 応答を作成する

Django で JSON 応答を作成する方法を学びます。

このページの内容

Django の JsonResponse を使うと、ビューから JSON にシリアライズ可能なデータを返せます。デフォルトでは辞書を受け取り、safe=False を指定するとリストを渡せます。モデルインスタンスや QuerySet を返す場合は、まず API で公開するフィールドを選び、適切な形に整えます。以下では、関数ベースビューとクラスベースビュー、リスト形式の応答、モデルデータの変換、低レベルの HttpResponse を使う方法を説明します。

Django の JsonResponse で JSON オブジェクトを返す

JsonResponse には、通常、辞書を渡します。Django が辞書をシリアライズし、応答のコンテンツタイプを JSON に設定するため、ビューからそのまま返せます。どちらのビュー形式でも使える簡単なデータ例を示します。

次の例を実行します。

このセクションのコードと表示されるラベルや出力は英語のままです。

import json

data = {"name": "Ada", "active": True}
print(json.dumps(data, separators=(",", ":")))

出力:

{"name":"Ada","active":true}

JsonResponse は django.http からインポートします。関数ベースビューは、たとえば def profile(request): return JsonResponse({"name": "Ada", "active": True}) と定義できます。クラスベースビューでは、django.views から View もインポートし、class ProfileView(View): get = lambda self, request: JsonResponse({"name": "Ada", "active": True}) のように定義します。これらの Django 固有のビュー形式を使うには、プロジェクトの設定が必要です。上の標準ライブラリの例が示すのは JSON のデータ形式であり、Django のリクエストや応答ではありません。

辞書をデフォルトで使うと、キーに名前を付けた拡張しやすい応答形式にできます。たとえば、API が現在 {"name": "Ada", "active": True} を返していても、トップレベルの型を変えずに後からキーを追加できます。値は JSON にシリアライズできるものにしてください。文字列、数値、真偽値、None、リスト、辞書などが一般的です。

JsonResponse で JSON 配列を返す

リストも有効な JSON 値ですが、JsonResponse は、別途指定しない限り辞書を想定します。トップレベルの値がリストの場合は safe=False を設定します。

return JsonResponse(["Django", "Python"], safe=False)

応答自体がコレクションの場合に、この形式を使います。件数やページネーション情報などのメタデータも必要なら、リストを含む辞書を返します。たとえば {"items": ["Django", "Python"], "count": 2} のようにできます。safe=False は許可されるトップレベルの形式を変えるもので、任意の Python オブジェクトをシリアライズ可能にするものではありません。

JSON を返す前にモデルと QuerySet のデータを変換する

Django のモデルインスタンスや QuerySet は、自動的には JSON にシリアライズできません。公開する応答に含めるフィールドを選び、各レコードを通常の Python 値に変換してから、結果を JsonResponse に渡してください。こうすることで、モデル内部のフィールドを誤って公開することも防げます。

たとえば、ビューで Blog を1件と複数件取得し、それぞれ明示的に整形できます。

one = Blog.objects.get(pk=1)

many = Blog.objects.all()

one_data = {"title": one.title, "likes": one.likes}

many_data = [{"title": blog.title, "likes": blog.likes} for blog in many]

return JsonResponse({"blog": one_data, "blogs": many_data})

これはデータの整形方法を示す例で、ビュー全体ではありません。Blog モデルとデータベースが設定済みであることを前提としています。画像、日付、関連オブジェクトなど、プリミティブ型ではないフィールドが必要な場合は、API の仕様に合う文字列、数値、真偽値、リスト、辞書などに明示的に変換してください。より大規模または複雑なシリアライズには、Django のシリアライザーも選択肢になります。詳しくはDjango のシリアライズに関するドキュメントを参照してください。

HttpResponse で JSON を手動で構築する

シリアライズの手順を自分で制御したい場合は、HttpResponse を使います。json と HttpResponse をインポートし、json.dumps で JSON 互換の Python 値をエンコードして、content_type に application/json を設定します。

import json

from django.http import HttpResponse

return HttpResponse(json.dumps({"name": "Ada"}), content_type="application/json")

渡した値をエンコードできれば、この低レベルの方法で JSON 応答を返せます。通常の辞書やリストには、JSON のエンコードとコンテンツタイプの設定を処理する JsonResponse のほうが、一般にわかりやすいでしょう。JsonResponse を使う場合と同様に、モデルインスタンスや QuerySet の結果は、まず明示的に JSON 互換の形式に変換してください。