Menu
CoddyTech

POST 후 리디렉션

Coddy Django 여정의 폼 섹션에 포함된 레슨. 20개 중 3번째.

이벤트를 추가한 다음 감사 페이지를 새로고침해 보세요. 브라우저에서 양식을 다시 보내겠냐고 묻고, 동의하면 이벤트가 두 번 추가됩니다. 해당 페이지는 POST에 대한 응답이었으므로, 페이지를 새로고침하면 POST가 다시 전송됩니다.

이 문제를 해결하는 패턴을 Post/Redirect/Get이라고 합니다. 저장한 후 뷰는 리디렉션으로 응답합니다. 상태 코드는 302이고 새 주소를 제공합니다. 브라우저는 해당 주소를 GET으로 열므로, 페이지를 새로고침해도 GET만 반복됩니다.

django.shortcuts의 redirect()는 {% url %}과 같은 방식으로 URL 이름을 받습니다. 장바구니에 상품을 추가하는 쇼핑몰의 예입니다.

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

인수가 필요한 URL에는 이름으로 인수를 전달합니다. 예를 들면 redirect("shop:product", pk=7)입니다.

challenge icon

챌린지

쉬움

new_event에서 이벤트를 만든 후 event_added.html을 렌더링하는 대신 새 이벤트의 페이지로 리디렉션하세요. 이제 사용하는 곳이 없으므로 event_added.html을 삭제해도 됩니다.

이벤트를 추가한 다음 해당 페이지를 새로고침하세요. 브라우저에서 양식을 다시 제출할지 묻지 않습니다.

직접 해보기

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

폼의 모든 레슨

직접 연습해 보세요: Django 플레이그라운드