Django学习(四)- 表单提交
1. CSRF
CSRF, Cross Site Request Forgery, 跨站点伪造请求,防止恶意访问的请求验证
django自己集成了一个快捷进行验证配置的方法
django 第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个 token 放在 cookie 里。然后每次 POST 请求都会带上这个 token,这样就能避免被 CSRF 攻击。
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
仔细回去查看,会发现设置文件里面关于中间件当中就有一项是django.middleware.csrf.CsrfViewMiddleware,所以我么也不用了解太多,直接用就行了,每次你的html中要使用表单form时,在里面加上{% csrf_token %}即可
polls/templates/polls/detail.html
<h1>{{ question.question_text }}</h1>
{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
{% 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 %}
<input type="submit" value="Vote">
</form>
- 相信学过html的同学对表单提交的知识不会陌生,这里需要在action里面设置处理方法以及请求方式
2. forloop
>forloop用于处理模板里面的循环,比如对循环次数的获取,对外层循环对象的获取等等
image.png{% for f in friendslist %}
{% if forloop.first %}
// display something
{% endif %}
// display stuff
{% if forloop.last %}
// display something
{% endif %}
{% endfor %}
{% for outerItem in outerItems %}
{% for item in items%}
<div>{{ forloop.counter }}. {{ item }}</div>
#访问外层循环
<div>{{forloop.parentloop.counter}}</div>
{% endfor %}
{% endfor %}
3. 表单实例
我们这里拿一个板块对前面的html表单做返回演示
polls/urls.py
path('<int:question_id>/vote/', views.vote, name='vote'),
polls/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from .models import Choice, Question
# ...
def vote(request, question_id):
question = get_object_or_404(Question, pk=question_id)
try:
selected_choice = question.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the question voting form.
return render(request, 'polls/detail.html', {
'question': question,
'error_message': "You didn't select a choice.",
})
else:
selected_choice.votes += 1
selected_choice.save()
# Always return an HttpResponseRedirect after successfully dealing
# with POST data. This prevents data from being posted twice if a
# user hits the Back button.
return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))
4. 表单对象获取
request.GET / request/POST,
request.POST
是一个类似字典的对象,允许您按键名访问提交的数据。在这种情况下,request.POST['choice']
返回所选选项的ID,作为字符串。request.POST
值始终是字符串。
- 请注意,Django还提供
request.GET
了以相同方式访问GET数据 - 但我们request.POST
在代码中明确使用,以确保数据仅通过POST调用进行更改。 - 如果
choice
在POST数据中没有提供,则会引发KeyError
5. 请求重定向
这里涉及到两个新方法,
HttpResponseRedirect
和reverse()
如字面意思翻译,就是重定向以及倒转,重定向不难理解,就是转到另外一个url,但是这里为了避免url硬编码,我们可以使用reverse方法
前面的url定义是从url映射到相应的视图函数,这里恰好相反,我们从试图函数方向映射到对应的url从而进行请求重定向