06-django-request

Request

  • request.method: 获取请求方式
  • request.GET: 获取 GET 请求的参数
  • request.POST: 获取 POST 请求的参数

GET & POST

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
<form action="{% 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 %}
<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}">
<label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>
{% endfor %}
</fieldset>
<input type="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
def vote(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,)))
  • 注意后台处理中数据库数据的 selected_choice 并没有添加互斥所, 多个用户同时请求更新这个数据时可能会出现错误, 解决方案后续更新…
  • reverse 函数解决了目标 url 的硬编码问题; 当然可以直接使用 django.shortcuts.redirect