django 提交表单 提示403:CSRF verification failed
后台日志:
UserWarning: A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.
"A {% csrf_token %} was used in a template, but the context "
[15/Mar/2018 15:20:40] "GET /users/login/ HTTP/1.1" 200 2193
Forbidden (CSRF token missing or incorrect.): /users/login/
[15/Mar/2018 15:20:47] "POST /users/login/ HTTP/1.1" 403 2497
我前端模板form代码如下
<form class="m-t" role="form" method="post" action={% url 'users:login' %} autocomplete="off">
{% csrf_token %}
{{ form_login.as_p }}
<div class="auto-box marb38">
<button type="submit" class="btn btn-primary block full-width m-b">Login</button>
<input type="hidden" name="next" value="{{ redirect_url }}" />
</div>
</form>
view代码如下
class LoginView(View):
'''用户登录'''
error=""
def get(self, request):
form_login = LoginForm()
redirect_url = request.GET.get('next', '')
return render_to_response('users/login_two_columns.html',{"form_login":form_login,"redirect_url":redirect_url})
def post(self, request):
form_login = LoginForm(request.POST)
if form_login.is_valid():
username = form_login.cleaned_data['username']
password = form_login.cleaned_data['password']
user = authenticate(username=username, password=password)
# 如果不是null说明验证成功
if user is not None:
# login_in 两参数:request, user
# request是要render回去的。这些信息也就随着返回浏览器。完成登录
login(request, user)
# request.session['is_login']=request.user
request.session["username"] = request.user.id
request.session.set_expiry(600)
# 跳转到首页 user request会被带回到首页
redirect_url = request.POST.get('next', '')
if redirect_url:
return HttpResponseRedirect(redirect_url)
# 跳转到首页 user request会被带回到首页
return HttpResponseRedirect(reverse("index"))
return render_to_response( 'users/login_two_columns.html',
{"msg": "用户名不存在!",
"form_login": form_login,
})
模板中也确实加了{% csrf_token %}
后来查看了这篇文章解决了这个问题
https://*.com/questions/24642676/userwarning-a-csrf-token-was-used-in-a-template-views-py-not-recognisei
解决:
把render_to_response改成render即可
结论:
{% csrf_token %}的生成需要request的传入,而render_to_response与render在源码上的差别,只在于是否有request的传入,所以render可以工作而render_to_response不可以