2011-11-30 53 views
14

錯誤是在位置http://127.0.0.1:8000/fileupload/form.pyDjango:CSRF令牌丟失或不正確

我有django的1.3版本。我曾嘗試在別人的問題中指定localhost:8000,但這不適用於我。我想要一個文件上傳的形式,但我收到一個錯誤,form.py沒有CSRF令牌。

form.py:

class UploadFileForm(forms.Form): 

    title = forms.CharField(max_length=50) 
    file = forms.FileField() 

views.py:

def upload_file(request): 

    c = {} 
    c.update(csrf(request)) 

    if (not request.user.is_authenticated()) or (request.user == None): 
     return HttpResponseRedirect("/?error=11") 


    if request.method == 'POST': 
     form = c['UploadFileForm'] = UploadFileForm(request.POST, request.FILES, c, context_instance=RequestContext(request)) 

     if c['UploadFileForm'].is_valid(): 
     handle_uploaded_file(request.FILES['file']) 
     return HttpResponseRedirect('/success/url/') 

    else: 
     form = c['UploadFileForm'] = UploadFileForm() 
    return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']}) 

upload.html:

{% block main_content %} 


    <form action="fileupload/form.py" enctype="multipart/form-data" method="POST"> 
    {% csrf_token %} 
    <table> 

     <tr><td>Title:</td><td><input type="text" name="title" /></td></tr> 
     <tr><td>File:</td><td><input type="file" name="file" /></td></tr> 
    </table> 
     <input type="submit" value="Submit" class = "float_right button_input" /> 

    </form> 

{% endblock main_content %} 

我很爲難,請告訴我一些東西去嘗試。謝謝

回答

29

您需要選擇render_to_response中傳遞RequestContextcsrf_token

對於這樣的:(views.py

from django.template import RequestContext 

... 

return render_to_response('fileupload/upload.html', {'form': c['UploadFileForm']}, RequestContext(request)) 
# Added RequestContext 

此通行證CSRF到模板的令牌。

+0

您已經在模板中使用了'{%csrf_token%}',所以這應該起作用。 –

+0

加上RequestContext我得到一個類型錯誤__init __()得到了一個意外的關鍵字參數'context_instance' – user1072646

+0

謝謝,我只是想通了。它像你說的那樣添加RequestContext(request),並從if語句中刪除c和context_instance =。如果你改變你的答案,包括我會標記它是正確的。 – user1072646

0

我的回答類似於@Yugal Jindle上面的答案。

我使用Django的1.10,我也有類似的問題,它的工作對我來說編輯

return render_to_response(param1, param2) 

return render(request, param1, param2) 

後附言請確保你有你的中間件變量下面的線在settings.py

'django.middleware.csrf.CsrfViewMiddleware' 
0

如果使用@cache_page(60 * 15)裝飾它也可能發生。如果使用包含CSRF令牌的表單緩存頁面,則只會緩存第一個用戶的CSRF令牌。所以它有時很難調試。從Django documentation

更多信息如果csrf_token模板標籤由一個模板使用(或的get_token 函數被調用一些其他的方式),CsrfViewMiddleware將增加 餅乾和一個Vary:Cookie標題的響應。這意味着如果 被指示使用(UpdateCacheMiddleware在所有其他中間件之前),則該中間件將與緩存中間件配合良好。但是,如果您在各個視圖上使用緩存修飾器,那麼CSRF 中間件還不能設置Vary頭或CSRF cookie,並且響應將被緩存而不會有任何一個。在 這種情況下,這將需要一個CSRF令牌的任何意見要插入 你應該使用django.views.decorators.csrf.csrf_protect() 裝飾第一:

from django.views.decorators.cache import cache_page 
from django.views.decorators.csrf import csrf_protect 

@cache_page(60 * 15) 
@csrf_protect 
def my_view(request): 
    ... 
相關問題