Django POST请求失败

我在表单中使用POST时出现错误,即使我已将csrf_token添加到我的表单中....

错误

禁止的(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),

回答(2)

2 years ago

您尚未将令牌添加到表单中 .

您已添加代码 {% csrf_token %} ,但 django.core.context_processors.csrf aren 't being used so the template tag isn' t实际上输出任何内容(模板标签无提示失败) .

而不是使用 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 years ago

你想看点#3 here . 你正在返回一个简单的HttpResponse,所以我认为正在跳过csrf上下文处理器 . 您可能需要考虑使用django.shortcuts.render . 此外,在您的模板中,您的表单方法是"post",但在您的视图中,您're checking request.GET. That'与您所拥有的CSRF问题无关,但您可能想要修复它 .