Menu
CoddyTech

Supprimer une tâche

Fait partie de la section API JSON du Journey Django de Coddy. Leçon 10 sur 19.

Une tâche terminée doit disparaître, pas seulement être cochée : DELETE /api/tasks/1/ supprime la tâche 1, et il n’y a alors rien à renvoyer.

Pour cela, HTTP dispose du statut 204 No Content : la requête a réussi et la réponse n’a pas de corps. Un JsonResponse écrit toujours un corps, même {}. Un HttpResponse simple, avec uniquement un statut, n’envoie rien d’autre :

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

Conserve la vérification 404 en premier, afin que la suppression d’une tâche inexistante renvoie toujours une réponse 404.

Une URL, trois méthodes : GET lit la tâche, PATCH la modifie, DELETE la supprime. Une URL par ressource, avec la méthode comme verbe, c’est ce qu’on appelle une API REST.

challenge icon

Défi

Facile

Permets aux programmes de supprimer une tâche avec DELETE /api/tasks/<id>/. Dans tasks/views.py, autorise "DELETE" sur task_detail, puis supprime la tâche et réponds avec le statut 204 et un corps vide. Si une tâche est introuvable, la réponse reste 404.

Exécute deux fois la ligne ci-dessous dans l’onglet Shell : elle affiche 204, puis 404, car la tâche 1 n’existe plus.

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

Essayez vous-même

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

Toutes les leçons de API JSON

Entraînez-vous par vous-même : Playground Django