Eliminar una tarea
Parte de la sección API JSON del Journey de Django de Coddy. Lección 10 de 19.
Una tarea completada debe desaparecer, no solo quedar marcada: DELETE /api/tasks/1/ elimina la tarea 1, y después no hay nada que enviar como respuesta.
Para eso, HTTP tiene 204 No Content: la solicitud se procesó correctamente y la respuesta no tiene cuerpo. JsonResponse siempre escribe un cuerpo, incluso {}. Un HttpResponse simple que solo tenga un estado no envía nada más:
return HttpResponse(status=204)Mantén primero la comprobación del 404, para que al eliminar una tarea inexistente se siga respondiendo con 404.
Una URL, tres métodos: GET lee la tarea, PATCH la modifica, DELETE la elimina. Una URL por recurso, con el método como verbo, es lo que se conoce como una API REST.
Desafío
FácilPermite que los programas eliminen una tarea con DELETE /api/tasks/<id>/:
- Permite
"DELETE"entask_detail. - Elimina la tarea y responde con
204y un cuerpo vacío. - Si falta una tarea, la respuesta sigue siendo 404.
Pulsa Run y, después, en la pestaña Shell: from django.test import Client; print(Client().delete("/api/tasks/1/").status_code) imprime 204.
Pruébalo tú mismo
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))
Todas las lecciones de API JSON
2Lectura de solicitudes
Filtrar con una consultaCrear con POST5Proyecto: Organizar el trabajo
Proyecto: PrioridadesProyecto: Borrar las tareas completadasPractica por tu cuenta: Playground de Django