16

我想为我的网站实现登录。我基本上将 Django Book 中的以下内容复制并粘贴在一起。但是,在提交我的注册表单时,我仍然收到错误消息(CSRF 验证失败。请求中止。)。有人能告诉我是什么引发了这个错误以及如何解决它吗?

这是我的代码:

视图.py:

# Create your views here.
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            new_user = form.save()
            return HttpResponseRedirect("/books/")
    else:
        form = UserCreationForm()
    return render_to_response("registration/register.html", {
        'form': form,
    })

注册.html:

<html>
<body>

{% block title %}Create an account{% endblock %}

{% block content %}
  <h1>Create an account</h1>

  <form action="" method="post">{% csrf_token %}
      {{ form.as_p }}
      <input type="submit" value="Create the account">
  </form>
{% endblock %}
</body>
</html>
4

7 回答 7

19

我遇到了完全相同的问题 - Blue Peppers 的回答让我走上了正轨。将 RequestContext 添加到表单视图可以解决问题。

from django.template import RequestContext

和:

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
           new_user = form.save()
           return HttpResponseRedirect("/books/")
    else:
        form = UserCreationForm()
    c = {'form': form}
    return render_to_response("registration/register.html", c, context_instance=RequestContext(request))

这为我修好了。

于 2010-08-27T14:58:25.200 回答
8

我正在使用Django 1.2.3,我遇到了一些间歇性问题:

要做的事情:

确保您的模板中存在 csrf 令牌

<form action="" method="post">{% csrf_token %}

使用 RequestContext

return render_to_response('search-results.html', {'results' : results}, context_instance=RequestContext(request) )

确保您也为 GET 使用 RequestContext,如果它们由相同的视图函数处理,并呈现相同的模板。

IE:

if request.method == 'GET':
    ...
    return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request) )
elif request.method == 'POST':
    ...
    return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request))

不是:

if request.method == 'GET':
    ...
    return render_to_response('search-results.html', {'results':results})
elif request.method == 'POST':
    ...
    return render_to_response('search-results.html', {'results':results}, context_instance=RequestContext(request))

确保 'django.middleware.csrf.CsrfViewMiddleware' 在你的 settings.py 中列出

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
)
于 2011-01-16T19:47:40.333 回答
6

假设您使用的是 Django 1.2.x,只需在之前添加{{form.as_p}}

{% csrf_token %}

要了解为什么,请查看CSRF 文档

于 2010-07-07T17:37:27.640 回答
2

您需要添加csrf(request)到您的上下文中。

from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.core.context_processors import csrf

def register(request):
    if request.method == 'POST':
        form = UserCreationForm(request.POST)
        if form.is_valid():
            new_user = form.save()
            return HttpResponseRedirect("/books/")
    else:
        form = UserCreationForm()
    con = {'form': form}
    con.update(csrf(request))
    return render_to_response("registration/register.html", con)

您可能需要为此将您的上下文变成一个Context对象,而不是 a dict,但原则是合理的。

于 2010-07-07T17:37:13.163 回答
1

如果您不想添加{% csrf_token %}到每个表单中,请将这 2 个中间件添加到设置文件中。

MIDDLEWARE_CLASSES = (
    #...
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.middleware.csrf.CsrfResponseMiddleware',
)
于 2010-07-07T21:52:24.047 回答
1

稍后回答。

现在render可以使用代替context_instance=RequestContext(request)

from django.shortcuts import render
return render(request, "registration/register.html", {
        'form': form,
    })
于 2015-07-01T10:11:05.023 回答
1

如果您打算使用 {% csrf_token %},请尝试从 settings.py 的 MIDDLEWARE 列表中删除以下行:

'django.middleware.csrf.CsrfViewMiddleware',

为我工作......

于 2018-10-23T10:50:07.677 回答