Menu
CoddyTech

Zulässige Methoden

Teil des Abschnitts JSON-APIs der Django-Journey von Coddy. Lektion 8 von 19.

Sende DELETE /api/tasks/, und die Anfrage fällt durch bis zu dem Code, der Aufgaben auflistet: 200, als hätte es funktioniert. Ein Programm, das etwas löschen wollte, glaubt nun, es hätte das getan.

Die ehrliche Antwort lautet 405 Method Not Allowed. Die Decorators in django.views.decorators.http liefern sie, bevor deine View ausgeführt wird, zusammen mit einem Allow-Header, der auflistet, was die View akzeptiert:

@require_POST
def subscribe(request):
    ...


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

require_GET und require_POST sind die Kurzformen für jeweils eine Methode. Eine View kann zwei Decorators tragen, einen pro Zeile, etwa @csrf_exempt über @require_POST. Erlaube genau die Methoden, für die der Code einer View etwas tut.

challenge icon

Aufgabe

Einfach

Gib für Methoden, die eine Ansicht nicht verarbeitet, den Statuscode 405 zurück:

  • task_list akzeptiert GET und POST.
  • stats und task_detail akzeptieren nur GET.

Klicke auf „Run“ und gib dann im Tab „Shell“ Folgendes ein: from django.test import Client; print(Client().delete("/api/stats/").status_code). Es wird 405 ausgegeben.

Probier es selbst

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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in JSON-APIs

Übe selbstständig: Django-Playground