POST 后重定向
本课属于 Coddy Django 学习旅程的“表单”单元。第 3 课,共 20 课。
添加一个活动,然后重新加载感谢页面:浏览器会询问是否重新发送表单,同意后会重复添加该活动。该页面是对 POST 的响应,因此重新加载时会再次发送 POST。
解决方法是一种叫作 Post/Redirect/Get 的模式。保存后,视图会返回一个重定向:状态码 302 和一个新地址。浏览器会使用 GET 打开该地址,因此重新加载时只会重复发送 GET。
redirect() 来自 django.shortcuts,它接收一个 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)。
挑战
简单在 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 在线编辑器