Menu
CoddyTech

Redirigir después de POST

Parte de la sección Formularios del Journey de Django de Coddy. Lección 3 de 20.

Añade un evento y después vuelve a cargar la página de agradecimiento: el navegador ofrece volver a enviar el formulario, y si aceptas, el evento se añade dos veces. Esa página era la respuesta a un POST, así que volver a cargarla envía de nuevo el POST.

La solución es un patrón llamado Post/Redirect/Get. Después de guardar, la vista responde con una redirección: estado 302 y una nueva dirección. El navegador abre esa dirección con un GET, así que volver a cargarla solo repite el GET.

redirect() de django.shortcuts recibe un nombre de URL, igual que {% url %}. Una tienda que añade un artículo al carrito:

from django.shortcuts import redirect


def add_to_cart(request, pk):
    if request.method == "POST":
        CartItem.objects.create(product_id=pk)
        return redirect("shop:cart")
    ...

Una URL con un argumento lo recibe por nombre: redirect("shop:product", pk=7).

challenge icon

Desafío

Fácil

En new_event, después de crear el evento, redirige a la página del evento recién creado en lugar de renderizar event_added.html. Puedes eliminar event_added.html; ahora ya no se usa.

Añade un evento y después vuelve a cargar su página: el navegador no te pide que vuelvas a enviar el formulario.

Pruébalo tú mismo

from django.shortcuts import get_object_or_404, render

from .models import Event


def event_list(request):
    q = request.GET.get("q", "")
    events = Event.objects.all()
    if q:
        events = events.filter(title__icontains=q)
    return render(request, "events/event_list.html", {"events": events, "q": q})


def event_detail(request, pk):
    event = get_object_or_404(Event, pk=pk)
    return render(request, "events/event_detail.html", {"event": event})


def new_event(request):
    if request.method == "POST":
        Event.objects.create(
            title=request.POST["title"],
            date=request.POST["date"],
            place=request.POST["place"],
        )
        return render(request, "events/event_added.html")
    return render(request, "events/new_event.html")

Todas las lecciones de Formularios

Practica por tu cuenta: Playground de Django