Menu
CoddyTech

按 ID 获取单个任务

本课属于 Coddy Django 学习旅程的“JSON API”单元。第 3 课,共 19 课。

现在,读取列表的程序想通过自己的 URL 获取一项任务:/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。

challenge icon

挑战

简单

为单个任务添加一个端点。

  1. 在 tasks/views.py 中,添加 task_detail(request, pk)。它会以 JSON 格式返回 task_to_dict(task)。如果没有对应 ID 的任务,则返回状态码 404 和 {"error": "Task not found"}。
  2. 在 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)
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

JSON API中的所有课

自己练习: Django 在线编辑器