Django:CSRF令牌丢失或不正确

时间:2011-11-30 04:35:23

标签: python django django-views

错误位于http://127.0.0.1:8000/fileupload/form.py

位置

我有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 %}

我很难过,请告诉我一些尝试的事情。谢谢

4 个答案:

答案 0 :(得分:31)

您需要在RequestContext

的render_to_response中传递csrf_token

为此:( views.py

from django.template import RequestContext

...

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

这会将csrf的标记传递给模板。

答案 1 :(得分:1)

我的回答类似于@Yugal Jindle的答案。

我正在使用Django 1.10,我遇到了类似的问题,编辑后它对我有用

return render_to_response(param1, param2)

return render(request, param1, param2)

P.S。确保settings.py

中的MIDDLEWARE变量中包含以下行
'django.middleware.csrf.CsrfViewMiddleware'

答案 2 :(得分:0)

如果使用@cache_page(60 * 15)装饰器,也会发生这种情况。如果使用包含CSRF令牌的表单缓存页面,则只缓存第一个用户的CSRF令牌。所以有时候很难调试。

来自Django documentation的更多信息

  

如果模板使用 csrf_token 模板标记(或 get_token   函数被调用其他方式), CsrfViewMiddleware 将添加一个   Cookie和响应的 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):
    ...

答案 3 :(得分:0)

对于我的情况,我使用ajax将数据发布到我的视图函数,然后发生同样的错误,因此解决它的简单方法是更改​​数据

data:{ 'k':'v' }

data:{ 'k':'v' ,addcsrfmiddlewaretoken:'{{ csrf_token }}',}

因为我们手动添加了一个 csrf-token,所以它不会丢失或不正确。

希望对你有用:)