Menu
CoddyTech

Eine Klasse pro Ressource

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

task_detail besteht jetzt aus einer Reihe von if request.method == ...-Blöcken sowie einer Liste von Methoden, die damit Schritt halten muss. Die Basisklasse View von Django, von der jede von dir verwendete generische Ansicht abgeleitet ist, übernimmt diese Verwaltung.

Gib der Klasse für jede HTTP-Methode eine eigene Methode, deren Name kleingeschrieben ist. View ruft die Methode auf, die nach der Anfrage benannt ist, und antwortet bei jeder anderen Methode mit 405. Werte aus der URL werden wie bei einer Funktionsansicht nach request übergeben, und die Route verwendet .as_view(). Das Farbdesign eines Besuchers als Ressource:

@method_decorator(csrf_exempt, name="dispatch")
class Theme(View):
    def get(self, request):
        return JsonResponse({"theme": request.session.get("theme", "light")})

    def put(self, request):
        data = json.loads(request.body)
        request.session["theme"] = data["theme"]
        return JsonResponse({"theme": data["theme"]})

@csrf_exempt funktioniert bei Funktionen. Bei einer Klasse platziert method_decorator es auf dispatch, der Methode, die jede Anfrage durchläuft.

challenge icon

Aufgabe

Mittel

Wandle task_detail in eine Klasse TaskDetail(View) um:

  • Methoden get, patch und delete, die jeweils dasselbe tun wie die Funktion, einschließlich 404.
  • Mit method_decorator von CSRF ausnehmen.
  • Die Route verwendet views.TaskDetail.as_view() und heißt weiterhin task_detail.

Klicke auf „Run“ und öffne dann /api/tasks/1/: Die Aufgabe wird wie zuvor angezeigt.

Probier es selbst

import json

from django.http import HttpResponse, 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", "DELETE"])
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 == "DELETE":
        task.delete()
        return HttpResponse(status=204)
    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))
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