Menu
CoddyTech

Menghapus Tugas

Termasuk bagian API JSON dalam perjalanan Django di Coddy. Pelajaran 10 dari 19.

Tugas yang selesai seharusnya dihapus, bukan hanya dicentang: DELETE /api/tasks/1/ menghapus tugas 1, lalu tidak ada apa pun yang perlu dikirim kembali.

Untuk itu, HTTP menyediakan 204 No Content: permintaan berhasil dan respons tidak memiliki isi. JsonResponse selalu menulis isi, bahkan {}. HttpResponse biasa yang hanya memiliki status tidak mengirim apa pun lagi:

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

Pastikan pemeriksaan 404 dilakukan lebih dahulu, agar menghapus tugas yang tidak ada tetap menghasilkan respons 404.

Satu URL, tiga metode: GET membaca tugas, PATCH mengubahnya, DELETE menghapusnya. Satu URL untuk setiap sumber daya, dengan metode sebagai kata kerja, itulah yang disebut orang sebagai API REST.

challenge icon

Tantangan

Mudah

Izinkan program menghapus tugas dengan DELETE /api/tasks/<id>/. Di tasks/views.py, izinkan "DELETE" pada task_detail, lalu hapus tugas tersebut dan berikan respons dengan status 204 dan isi kosong. Jika tugas tidak ditemukan, responsnya tetap 404.

Jalankan baris di bawah ini dua kali di tab Shell: baris ini mencetak 204, lalu 404, karena tugas 1 sudah tidak ada.

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

Coba sendiri

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

Semua pelajaran di API JSON

Latihan sendiri: Playground Django