Menu
CoddyTech

الأساليب المسموح بها

جزء من قسم واجهات API بصيغة JSON في رحلة Django على Coddy. الدرس 8 من 19.

أرسل DELETE /api/tasks/، فينتقل الطلب إلى الشيفرة التي تعرض المهام: 200، وكأن العملية نجحت. والآن يعتقد برنامج طلب حذف شيء ما أنه فعل ذلك.

الإجابة الصادقة هي 405 Method Not Allowed. تمنحك أدوات التزيين في django.views.decorators.http هذه الإجابة قبل تشغيل العرض، مع ترويسة Allow التي تسرد الطرق التي يقبلها العرض:

@require_POST
def subscribe(request):
    ...


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

إن require_GET وrequire_POST صيغتان مختصرتان لطلب طريقة واحدة. يمكن أن يحمل العرض أداتي تزيين، واحدة في كل سطر، مثل @csrf_exempt فوق @require_POST. اسمح فقط بالطرق التي تنفذ شيفرة العرض إجراءً لها.

challenge icon

التحدي

سهل

أعِد الرمز 405 للطرق التي لا يتعامل معها العرض:

  • يقبل task_list الطريقتين GET وPOST.
  • يقبل كل من stats وtask_detail الطريقة GET فقط.

اضغط على Run، ثم في علامة تبويب Shell: تطبع from django.test import Client; print(Client().delete("/api/stats/").status_code) الرمز 405.

جرّب بنفسك

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 iconاختبر نفسك

يتضمن هذا الدرس اختبارًا قصيرًا. ابدأ الدرس للإجابة عليه وتتبّع تقدمك.

جميع دروس واجهات API بصيغة JSON

تدرّب بنفسك: Playground لـ Django