Menu
CoddyTech

Métodos permitidos

Parte de la sección API JSON del Journey de Django de Coddy. Lección 8 de 19.

Envía DELETE /api/tasks/ y la ejecución continúa hasta el código que enumera las tareas: 200, como si hubiera funcionado. Un programa que pidió eliminar algo ahora cree que lo hizo.

La respuesta correcta es 405 Method Not Allowed. Los decoradores de django.views.decorators.http la proporcionan antes de que se ejecute tu vista, con un encabezado Allow que enumera lo que acepta la vista:

@require_POST
def subscribe(request):
    ...


@require_http_methods(["GET", "PUT"])
def profile(request):
    ...

require_GET y require_POST son las formas abreviadas para un solo método. Una vista puede llevar dos decoradores, uno por línea, como @csrf_exempt encima de @require_POST. Permite exactamente los métodos para los que el código de una vista realiza alguna acción.

challenge icon

Desafío

Fácil

Responde con 405 para los métodos que una vista no admite:

  • task_list acepta GET y POST.
  • stats y task_detail aceptan solo GET.

Pulsa Run y, después, en la pestaña Shell: from django.test import Client; print(Client().delete("/api/stats/").status_code) imprime 405.

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 .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()})


def stats(request):
    data = {
        "total": Task.objects.count(),
        "done": Task.objects.filter(done=True).count(),
    }
    return JsonResponse(data)


@csrf_exempt
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)


def task_detail(request, pk):
    task = Task.objects.filter(pk=pk).first()
    if task is None:
        return JsonResponse({"error": "Task not found"}, status=404)
    return JsonResponse(task_to_dict(task))
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de API JSON

Practica por tu cuenta: Playground de Django