Menu
CoddyTech

Xóa một tác vụ

Thuộc phần API JSON trong hành trình Django của Coddy. Bài học 10 trên 19.

Một nhiệm vụ đã hoàn thành cần biến mất, chứ không chỉ được đánh dấu: DELETE /api/tasks/1/ xóa nhiệm vụ 1, rồi không còn gì để gửi lại.

HTTP có mã trạng thái 204 No Content cho trường hợp này: yêu cầu đã được xử lý thành công và phản hồi không có nội dung. JsonResponse luôn ghi nội dung vào phản hồi, kể cả {}. Một HttpResponse thuần chỉ có mã trạng thái sẽ không gửi gì khác:

def mark_read(request, pk):
    Notification.objects.filter(pk=pk).update(read=True)
    return HttpResponse(status=204)

Hãy giữ bước kiểm tra 404 ở đầu tiên, để việc xóa một nhiệm vụ không tồn tại vẫn trả về mã 404.

Một URL, ba phương thức: GET đọc nhiệm vụ, PATCH thay đổi nhiệm vụ, DELETE xóa nhiệm vụ. Mỗi tài nguyên có một URL, còn phương thức đóng vai trò như động từ. Đó là cách tổ chức mà mọi người gọi là API REST.

challenge icon

Thử thách

Dễ

Cho phép các chương trình xóa một nhiệm vụ bằng DELETE /api/tasks/<id>/. Trong tasks/views.py, cho phép "DELETE" trong task_detail, sau đó xóa nhiệm vụ và phản hồi với mã trạng thái 204 cùng phần nội dung trống. Nếu không tìm thấy nhiệm vụ, phản hồi vẫn là 404.

Chạy dòng bên dưới hai lần trong thẻ Shell: dòng này in ra 204, sau đó là 404, vì nhiệm vụ 1 đã bị xóa.

from django.test import Client; print(Client().delete("/api/tasks/1/").status_code)

Tự làm thử

import json

from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_GET, require_http_methods

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()})


@require_GET
def stats(request):
    data = {
        "total": Task.objects.count(),
        "done": Task.objects.filter(done=True).count(),
    }
    return JsonResponse(data)


@csrf_exempt
@require_http_methods(["GET", "POST"])
def task_list(request):
    if request.method == "POST":
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({"error": "The body is not valid JSON."}, status=400)
        errors = {}
        title = data.get("title", "").strip()
        if not title:
            errors["title"] = "This field is required."
        if errors:
            return JsonResponse({"errors": errors}, status=400)
        task = Task.objects.create(
            title=title,
            priority=data.get("priority", "normal"),
        )
        return JsonResponse(task_to_dict(task), status=201)
    tasks = Task.objects.all()
    done = request.GET.get("done")
    if done == "true":
        tasks = tasks.filter(done=True)
    elif done == "false":
        tasks = tasks.filter(done=False)
    return JsonResponse([task_to_dict(task) for task in tasks], safe=False)


@csrf_exempt
@require_http_methods(["GET", "PATCH"])
def task_detail(request, pk):
    task = Task.objects.filter(pk=pk).first()
    if task is None:
        return JsonResponse({"error": "Task not found"}, status=404)
    if request.method == "PATCH":
        data = json.loads(request.body)
        if "title" in data:
            task.title = data["title"]
        if "done" in data:
            task.done = data["done"]
        task.save()
    return JsonResponse(task_to_dict(task))

Tất cả bài học trong API JSON

Tự luyện tập: Playground Django