POST 请求通常用于实现对后台数据库数据的更改, 一旦更改完毕, 便通常以一个 redirect 的形式返回到目标页面
Whenever you create a form that alters data server-side, use method=”post”. As the Python comment above points out, you should always return an HttpResponseRedirect after successfully dealing with POST data.
Post Request
1 2 3 4 5 6 7 8 9 10 11 12 13
<formaction="{% url 'polls:vote' question.id %}"method="post"> {% comment %} In short, all POST forms that are targeted at internal URLs should use the {% csrf_token %} template tag. {% endcomment %} {% csrf_token %} <fieldset> <legend><h1>{{ question.question_text }}</h1></legend> {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %} {% for choice in question.choice_set.all %} <inputtype="radio"name="choice"id="choice{{ forloop.counter }}"value="{{ choice.id }}"> <labelfor="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br> {% endfor %} </fieldset> <inputtype="submit"value="Vote"> </form>
通过 Form 实现 Post 请求:
action 支持非硬编码 url; action 默认将请求传给当前 url;
input 标签中的 name 属性为 POST 的键名, value 属性为 POST 的键值
label 标签的指向, 更人性化的选取
csrf 防止跨站请求伪造
csrf 防止跨站请求伪造
POST 请求时会自动传递 csrfmiddlewaretoken 这个参数, 生存期仅一次
如果使用其它工具直接重现请求: 如 Postman, 直接失败
Post Redirect
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defvote(request, pk): question = get_object_or_404(Question, pk=pk) try: selected_choice = question.choice_set.get(pk=request.POST['choice']) except (KeyError, Choice.DoesNotExist): return render(request, 'polls/detail.html', { 'question': question, 'error_message': "You didn't select a choice.", }) else: selected_choice.votes += 1 selected_choice.save() # reverse function helps avoid having to hardcode a URL in the view function. return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))