2013-02-23 123 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問題無關,但可能是您想要解決的問題。