Jedna klasa na zasób
Część sekcji API JSON ścieżki Django w Coddy. Lekcja 11 z 19.
task_detail jest teraz łańcuchem bloków if request.method == ... oraz listą metod, którą trzeba z nimi uzgadniać. Klasa bazowa Django View, na której opiera się każdy użyty przez ciebie widok ogólny, zajmuje się tym śledzeniem.
Dodaj do klasy po jednej metodzie dla każdej metody HTTP, nadając im nazwy pisane małymi literami. View wywołuje metodę, której nazwa odpowiada żądaniu, a dla każdej innej zwraca odpowiedź 405. Wartości z adresu URL pojawiają się po request, tak jak w widoku funkcyjnym, a trasa używa .as_view(). Motyw kolorystyczny odwiedzającego jako zasób:
@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 działa w przypadku funkcji. W przypadku klasy method_decorator nakłada go na dispatch — metodę, przez którą przechodzi każde żądanie.
Wyzwanie
ŚredniPrzekształć task_detail w klasę TaskDetail(View):
- Metody
get,patchidelete, z których każda wykonuje to, co robiła funkcja, włącznie z odpowiedzią 404. - Wyłącz ochronę CSRF za pomocą
method_decorator. - Trasa używa
views.TaskDetail.as_view()i nadal ma nazwętask_detail.
Naciśnij Run, a następnie otwórz /api/tasks/1/: zadanie wyświetla się tak jak wcześniej.
Spróbuj swoich sił
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))
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji API JSON
2Odczytywanie żądań
Filtrowanie za pomocą zapytaniaTworzenie za pomocą POST5Projekt: Porządkowanie zadań
Projekt: PriorytetyProjekt: Usuwanie ukończonych zadańPoćwicz samodzielnie: Edytor online Django