Django中的CSRF错误

18 投票
7 回答
28647 浏览
提问于 2025-04-16 00:57

我想为我的网站实现一个登录功能。我基本上是从《Django书》中复制粘贴了以下代码。但是,当我提交注册表单时,还是出现了一个错误(CSRF验证失败,请求被中止)。有人能告诉我这个错误是怎么产生的,以及如何解决吗?

这是我的代码:

views.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,
    })

register.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>

7 个回答

7

假设你正在使用Django 1.2.x版本,只需要在{{form.as_p}}之前加上这一行:

{% csrf_token %}

想要了解这样做的原因,可以查看一下CSRF文档

9

我正在使用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,如果它们由同一个视图函数处理,并且渲染同一个模板。

也就是说:

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))

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

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',
)
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))

这对我来说解决了问题。

撰写回答