Menu
CoddyTech

Eine Aufgabe löschen

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

Eine erledigte Aufgabe sollte verschwunden sein, nicht nur abgehakt: DELETE /api/tasks/1/ entfernt Aufgabe 1, und dann gibt es nichts zurückzusenden.

Dafür gibt es bei HTTP 204 Kein Inhalt: Die Anfrage war erfolgreich und die Antwort hat keinen Body. Eine JsonResponse schreibt immer einen Body, selbst {}. Eine einfache HttpResponse mit nur einem Status sendet nichts Weiteres:

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

Führe zuerst die 404-Prüfung durch, damit das Löschen einer nicht vorhandenen Aufgabe weiterhin mit 404 beantwortet wird.

Eine URL, drei Methoden: GET liest die Aufgabe, PATCH ändert sie, DELETE entfernt sie. Eine URL pro Ressource, wobei die Methode das Verb ist – so etwas nennt man eine REST-API.

challenge icon

Aufgabe

Einfach

Lass Programme eine Aufgabe mit DELETE /api/tasks/<id>/ löschen. Erlaube in tasks/views.py "DELETE" für task_detail, lösche dann die Aufgabe und antworte mit dem Status 204 und einem leeren Antworttext. Bei einer fehlenden Aufgabe wird weiterhin mit 404 geantwortet.

Führe die folgende Zeile zweimal im Tab „Shell“ aus: Sie gibt 204 und dann 404 aus, weil Aufgabe 1 nicht mehr vorhanden ist.

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

Probier es selbst

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

Alle Lektionen in JSON-APIs

Übe selbstständig: Django-Playground