Django:添加{% csrf_token %}后仍然出现CSRF验证失败
views.py:
def index(request):
return render_to_response('index.html', {})
def photos(request, artist):
if not artist:
return render_to_response('photos.html', {'error' : 'no artist supplied'})
photos = get_photos_for_artist(artist)
if not photos:
logging.error('Issue while getting photos for artist')
return render_to_response('photos.html', {'error': 'no matching artist found'})
return render_to_response('photos.html', {'photos': photos})
Index.html:
<html>
<head>
<title>find artist photos </title>
</head>
<body>
{% block error %} {% endblock %}
<form action="/photos" method="POST">
{% csrf_token %}
<label for="artist">Artist : </label>
<input type="text" name="artist">
<input type="submit" value="Search">
</form>
{% block content %}{% endblock %}
</body>
</html>
photos.html:
{% extends 'index.html' %}
{% block error %}
{% if error %}
<p> {{ error}} </p>
{% endif %}
{% endblock %}
{% block content %}
{% if photos %}
{% for photo in photos %}
{{ photo }}
{% endfor %}
{% endif %}
{% endblock%}
url.py:
urlpatterns = patterns('',
(r'', index),
(r'^time/$', current_datetime),
(r'^photos/(\w+)$', photos)
)
我甚至尝试过加上 {% csrf_token %}
,但还是没用
谢谢你
更新
我在日志中看到了这些信息
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.
warnings.warn("A {% csrf_token %} was used in a template, but the context did not provide the value. This is usually caused by not using RequestContext.")
这是在我给 render_to_response() 加上 context_instance=RequestContext(request) 之后出现的
7 个回答
3
这里有几个需要排查的问题:
请在网页浏览器中打开你的“index”页面,然后选择“查看源代码”,检查一下
{% csrf_token %}
是否被正确替换。它应该变成一个<input>
标签。如果没有替换成功,那说明你的 index 页面有问题。如果替换成功了,那就说明你的照片页面有问题。在
index.html
中的 POST URL 和urls.py
中的模式不匹配。你的urls.py
似乎是希望搜索词作为 URL 的一部分,但实际上你是把它作为 HTTP POST 参数发送的。你需要通过request.POST
来获取它。
5
假设你正在使用一个比较新的Django版本(1.3/1.4/dev),你可以按照以下步骤操作:
- 在
settings.py
文件中,把中间件django.middleware.csrf.CsrfViewMiddleware
加入到MIDDLEWARE_CLASSES
列表里。 - 在你的模板中,表单里要使用
{% crsf_token %}
。 - 在你的视图中,确保使用了
django.core.context_processors.csrf
这个上下文处理器,可以通过以下方式实现:- 使用
RequestContext
,这个来自django.template
- 直接从
from django.core.context_processors
导入csrf处理器
- 使用
示例
from django.template import RequestContext
from django.shortcuts import render_to_response
def my_view(request):
return render_to_response('my_template.html', {}, context_instance=RequestContext(request))
或者
from django.core.context_processors import csrf
from django.shortcuts import render_to_response
def my_view(request):
c = {csrf(request)}
return render_to_response('my_template.html', c)
参考资料
- Django 1.3中的csrf 或 Django 1.4中的csrf
- Django 1.3中的RequestContext 或 Django 1.4中的RequestContext
(这是为了将来和后来的观众留下的详细帖子)
9
在你每个会用到表单的视图里,都要加上 context_instance=RequestContext(request)
这一行代码:
return render_to_response('index.html', {}, context_instance=RequestContext(request) )
return render_to_response('photos.html', {'photos': photos}, context_instance=RequestContext(request) )