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.
Aufgabe
MittelWandle task_detail in eine Klasse TaskDetail(View) um:
- Methoden
get,patchunddelete, die jeweils dasselbe tun wie die Funktion, einschließlich 404. - Mit
method_decoratorvon CSRF ausnehmen. - Die Route verwendet
views.TaskDetail.as_view()und heißt weiterhintask_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))
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