IDで指定する1つのタスク
CoddyのDjangoジャーニー「JSON API」セクションの一部。レッスン 3/19。
一覧を読み取るプログラムが、今度は独自のURLにある1件のタスクを必要としています:/api/tasks/1/。ルートは詳細ページと同じように<int:pk>でidを受け取り、スターターにあるヘルパーtask_to_dict(task)がタスクを辞書に変換します。
新しい部分は、タスクが見つからない場合の処理です。get_object_or_404はDjangoのHTML 404ページを返しますが、プログラムはそれを読み取れません。そのためAPIもエラーをJSONで送り、適切なステータスコードを付けます。これはリクエストの結果を示す番号です:200 成功、403 禁止、404 見つからない。JsonResponseではstatusとして指定します:
return JsonResponse({"error": "Staff only"}, status=403)エラーとタスクのどちらを返すか選ぶには、例外を発生させずに行を検索します:filter(pk=...).first()は、行があればそれを返し、なければNoneを返します。
チャレンジ
簡単1 件のタスク用のエンドポイントを追加します。
tasks/views.pyにtask_detail(request, pk)を追加します。JSON としてtask_to_dict(task)を返します。その ID のタスクがない場合は、ステータス404と{"error": "Task not found"}を返します。tasks/urls.pyに、task_detailという名前のルート"api/tasks/<int:pk>/"を追加します。
/api/tasks/99/ を開くと、{"error": "Task not found"} が表示されます。
自分で試してみよう
from django.http import JsonResponse
from django.shortcuts import render
from .models import Task
def task_to_dict(task):
return {
"id": task.id,
"title": task.title,
"done": task.done,
"priority": task.priority,
}
def home(request):
return render(request, "tasks/home.html", {"tasks": Task.objects.all()})
def stats(request):
data = {
"total": Task.objects.count(),
"done": Task.objects.filter(done=True).count(),
}
return JsonResponse(data)
def task_list(request):
tasks = Task.objects.values("id", "title", "done", "priority")
return JsonResponse(list(tasks), safe=False)
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
JSON APIのすべてのレッスン
自分で練習してみよう: Djangoプレイグラウンド