【问题标题】:csrf error in djangodjango中的csrf错误
【发布时间】:2011-03-12 22:59:05
【问题描述】:

我想为我的网站实现登录。我基本上将 Django Book 中的以下内容复制并粘贴在一起。但是,在提交我的注册表单时,我仍然收到错误消息(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,
    })

注册.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>

【问题讨论】:

    标签: python django csrf django-csrf


    【解决方案1】:

    我遇到了完全相同的问题 - 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))
    

    这为我解决了问题。

    【讨论】:

    • 对于当前的 django,更好的解决方案是使用 render() 而不是 render_to_response()。
    【解决方案2】:

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

    'django.middleware.csrf.CsrfViewMiddleware',
    

    为我工作......

    【讨论】:

      【解决方案3】:

      稍后回答。

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

      from django.shortcuts import render
      return render(request, "registration/register.html", {
              'form': form,
          })
      

      【讨论】:

        【解决方案4】:

        我正在使用 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))
        

        确保“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',
        )
        

        【讨论】:

          【解决方案5】:

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

          MIDDLEWARE_CLASSES = (
              #...
              'django.middleware.csrf.CsrfViewMiddleware',
              'django.middleware.csrf.CsrfResponseMiddleware',
          )
          

          【讨论】:

          • @stevejalim 讽刺的是,docs 建议它仍然适用于 1.2,但它已被弃用。
          【解决方案6】:

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

          {% csrf_token %}

          要了解原因,请查看CSRF docs

          【讨论】:

          • 这样做对我来说还不够;需要 user433033 解决方案
          【解决方案7】:

          您需要将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 对象,而不是 dict,但原则是合理的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-03-21
            • 2017-05-28
            • 2015-03-31
            • 2016-03-20
            • 1970-01-01
            • 2013-05-25
            • 2013-02-15
            • 2018-04-10
            相关资源
            最近更新 更多