2013-02-23 120 views
0

我在使用我的形式POST即使我已经加了csrf_token到我的形式得到一个错误....Django的POST请求无

错误

禁止(403)

CSRF验证失败。请求中止。对未给予

帮助

原因: CSRF的cookie未设置。

一般而言,如果存在真正的跨站点请求伪造,或者Django的CSRF机制未正确使用,则可能发生这种情况。对于POST表单,您需要确保: •您的浏览器正在接受cookie。 •视图函数使用RequestContext作为模板,而不是Context。 •在模板中,每个POST表单内都有一个{%csrf_token%}模板标签,用于定位内部URL。 •如果您未使用CsrfViewMiddleware,则必须在使用csrf_token模板标签的任何视图以及接受POST数据的视图上使用csrf_protect。

由于您的Django设置文件中有DEBUG = True,因此您会看到本页的帮助部分。将其更改为False,并且只显示最初的错误消息。

您可以使用CSRF_FAILURE_VIEW设置来自定义此页面。

views.py 

def search_form(request): 
    return render_to_response('search_form.html') 
def search(request): 
    print 'request.post=', request.POST 
    print 'request.get=', request.GET 
    print 'request.method=', request.META.get('REQUEST_METHOD') 
    if 'q' in request.GET: 
     message = 'You searched for :%r' % request.GET['q'] 
    else: 
     message = 'You submitted an empty form' 

    return HttpResponse(message) 



search-form.html 

<html> 
<head> 
    <title>Search</title> 
</head> 
<body> 
    <form action="/polls/search/" method="post">{% csrf_token %} 
     <input type="text" name="q"> 
     <input type="submit" value="Search"> 
    </form> 
</body> 
</html> 

urls.py 
urlpatterns = patterns('',url(r'^$',views.index,name='index'), 
     url(r'^meta/',views.display_meta,name='meta'), 
     url(r'^search-form/$',views.search_form), 
     url(r'^search/',views.search), 

回答

0

您还没有将令牌添加到您的表单中。

您已添加代码{% csrf_token %},但未使用django.core.context_processors.csrf,因此模板标记实际上并未输出任何内容(模板标记无提示失败)。

而不是使用HttpResponse,你需要render_to_response()(用RequestContext)或只是render()(其中处理RequestContext你)。

在不同的笔记中,您不需要两个视图。 search应同时处理渲染的形式和加工形式 -

从django.shortcuts进口

渲染

def search(request): 
    if request.method == POST: 
     print 'request.post=', request.POST 
     print 'request.get=', request.GET 
     print 'request.method=', request.META.get('REQUEST_METHOD') 
     if 'q' in request.GET: 
      message = 'You searched for :%r' % request.POST['q'] 
     else: 
      message = 'You submitted an empty form' 
     return render(request, 'search_form.html', {'message': message}) 
    return render(request, 'search_form.html') 

然后{{ message }}变量添加到您的search_form.html模板 - 可能是某种形式的if语句来达到同样的你现在正在做的事 -

<body> 
    {% if message %} 
     <div> {{ message }} </div> 
    {% else %} 
     <form action="/polls/search/" method="post">{% csrf_token %} 
      <input type="text" name="q"> 
      <input type="submit" value="Search"> 
     </form> 
    {% endif %} 
</body> 
2

你想看点#3 here。你正在返回一个普通的HttpResponse,所以我认为csrf上下文处理器正在被跳过。您可能需要考虑使用django.shortcuts.render。另外,在你的模板中你的表单方法是“post”,但在你的视图中你正在检查request.GET。这与您遇到的CSRF问题无关,但可能是您想要解决的问题。