Menu
CoddyTech

Các phương thức được phép

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

Gửi DELETE /api/tasks/, yêu cầu sẽ chạy tiếp đến đoạn code liệt kê các tác vụ và trả về 200, như thể yêu cầu đã thành công. Chương trình yêu cầu xóa một thứ gì đó giờ tin rằng nó đã xóa xong.

Phản hồi chính xác là 405 Method Not Allowed. Các decorator trong django.views.decorators.http trả về phản hồi này trước khi hàm của bạn chạy, kèm theo header Allow liệt kê những phương thức mà hàm chấp nhận:

@require_POST
def subscribe(request):
    ...


@require_http_methods(["GET", "PUT"])
def profile(request):
    ...

require_GET và require_POST là các dạng viết tắt cho một phương thức. Một hàm có thể dùng hai decorator, mỗi decorator trên một dòng, như @csrf_exempt phía trên @require_POST. Chỉ cho phép chính xác những phương thức mà code trong hàm xử lý.

challenge icon

Thử thách

Dễ

Trong tasks/views.py, hãy trả về 405 cho những phương thức mà một view không xử lý. task_list chấp nhận GET và POST, với @csrf_exempt. stats và task_detail chỉ chấp nhận GET.

Chạy dòng bên dưới trong thẻ Shell: dòng này in ra 405.

from django.test import Client; print(Client().delete("/api/stats/").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 .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)


@csrf_exempt
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)


def task_detail(request, pk):
    task = Task.objects.filter(pk=pk).first()
    if task is None:
        return JsonResponse({"error": "Task not found"}, status=404)
    return JsonResponse(task_to_dict(task))
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

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

Tự luyện tập: Playground Django