Menu
CoddyTech

Redirect After POST

Part of the Forms section of Coddy's Django journey. Lesson 3 of 20.

Add an event, then reload the thanks page: the browser offers to send the form again, and agreeing adds the event twice. The page answers a POST, so a reload repeats the POST.

The fix is a pattern called Post/Redirect/Get. After saving, the view answers with a redirect: status 302 and a new address. The browser opens that address with a GET, so a reload repeats only the GET.

redirect() from django.shortcuts takes a URL name, the way {% url %} does. A shop that adds an item to the cart:

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")
    ...

A URL with an argument takes it by name: redirect("shop:product", pk=7).

challenge icon

Challenge

Easy

In new_event, after creating the event, redirect to the new event's own page instead of rendering event_added.html. The thanks template is then unused: delete it.

Press Run, add an event, and reload the page you land on.

Try it yourself

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")

All lessons in Forms

Practice on your own: Django playground