Una classe per risorsa
Fa parte della sezione API JSON del percorso Django di Coddy. Lezione 11 di 19.
task_detail ora è una catena di blocchi if request.method == ... più un elenco di metodi da mantenere sincronizzato. La classe base di Django View, alla base di ogni vista generica che hai usato, si occupa di questa gestione.
Assegna alla classe un metodo per ogni metodo HTTP, con il nome in minuscolo. View chiama quello che prende il nome dalla richiesta e risponde con 405 per qualsiasi altro metodo. I valori dall’URL arrivano dopo request, come in una vista funzione, e la route usa .as_view(). Il tema cromatico di un visitatore come risorsa:
@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 funziona sulle funzioni. Su una classe, method_decorator lo applica a dispatch, il metodo attraversato da ogni richiesta.
Sfida
MedioTrasforma task_detail in una classe TaskDetail(View):
- Metodi
get,patchedelete, ognuno dei quali fa ciò che faceva la funzione, incluso il 404. - Esentala dalla protezione CSRF con
method_decorator. - La route usa
views.TaskDetail.as_view(), mantenendo il nometask_detail.
Premi Run, poi apri /api/tasks/1/: l’attività viene visualizzata come prima.
Provalo tu
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))
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di API JSON
2Lettura delle richieste
Filtrare con una queryCreare con POST5Progetto: organizzare il lavoro
Progetto: le prioritàProgetto: cancellare le attività completateEsercitati da solo: Playground Django