django csrf_token未打印隐藏输入字段

7 投票
3 回答
5086 浏览
提问于 2025-04-17 12:53

我的 views.py 文件:

from django.core.context_processors import csrf
from django.views.decorators.csrf import csrf_protect
from django.http import *
from django.template import *
from django.shortcuts import *
# Create your views here.
@csrf_protect
def homepage(request):
        return render_to_response('index.html', {'files':os.listdir('/home/username/public_html/posters') })
@csrf_protect
def upload(request):
        return render_to_response('list.html', )

在我的模板 index.html 中:

<html>
<body>
<h1> All uploaded posters: </h1>
<form action='/posters/upload' method= 'POST'>{%csrf_token%}
<input type='file' name= 'uploadfile'>Upload new poster <input type="submit" value = "Upload">
</form>
{%for file in files %}
<a href = 'http://servername/~username/posters/{{file}}'>{{file}}</a> <br />
{%endfor%}
</body>
</html>

所以当我在浏览器中打开主页,查看源代码时,发现没有 csrf 令牌!

<html>
<body>
<h1> All uploaded posters: </h1>
<form action='/posters/upload' method= 'POST'>
<input type='file' name= 'uploadfile'>Upload new poster <input type="submit" value = "Upload">
</form>

<a href= ......

我错过了什么?

更新: 这个 帮助了我。

3 个回答

0

请看一下来自Django文档的内容。

装饰器方法 与其把CsrfViewMiddleware作为一种全面的保护措施,不如在需要保护的特定视图上使用csrf_protect装饰器,它的功能是完全一样的。这个装饰器必须同时用于那些在输出中插入CSRF令牌的视图,以及那些接受POST表单数据的视图。(这些视图通常是同一个函数,但不一定总是这样)。使用方法如下:

from django.views.decorators.csrf import csrf_protect
from django.template import RequestContext

@csrf_protect
def my_view(request):
    c = {}
    # ...
    return render_to_response("a_template.html", c,
                               context_instance=RequestContext(request))

单独使用这个装饰器并不推荐,因为如果你忘记使用它,就会留下安全隐患。采用“腰带和裤子”的策略,即同时使用这两种方法是可以的,而且开销也很小。

1

一旦你使用的是1.3版本(你应该使用这个版本),那么render这个快捷方式就提供了一种更简洁的方法来实现这个功能:

from django.shortcuts import render

def some_view(request):
    return render(request, 'template.html', context_dict)
9

你需要使用 RequestContext 才能使用 CSRF 中间件:

from django.template import RequestContext

# In your view:
return render_to_response('index.html'
    {'files':os.listdir('/home/username/public_html/posters') },
    context_instance=RequestContext(request))

顺便说一下,不推荐使用 csrf_protect 装饰器,因为如果你忘记使用它,就会留下安全隐患。

撰写回答