【问题标题】:Django CSRF verification failed. Request abortedDjango CSRF 验证失败。请求中止
【发布时间】:2012-12-07 22:52:06
【问题描述】:

我有一个模型:

class Tour(models.Model):

    owner_id = models.ForeignKey(User)
    name = models.CharField(max_length=50)
    location = models.ManyToManyField(Location)
    subscribers = models.ManyToManyField(User, related_name="sub")
    tour_date = models.DateField(null=True)
    description = models.CharField(max_length=300, null=True)

还有一个包含此表单的模板:

 <form method="post" action="/mytours/">
 {% csrf_token %}
 <input name="name" value="{{ name }}" class="pull-left" type="text" placeholder="Type the tour name... "></br>
 <input name="tour_date" value="{{ tour_date }}" type="text" id="datepicker" placeholder="Pick a tour date..."/>
  <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
  <button type="submit" class="btn btn-primary">Save</button>
</form>

在我看来,我正在尝试将表单中填写的内容添加到我的数据库中:

if request.method == 'POST':
        location = Location.objects.get(id=1)
        name = request.POST.get('name', '')
        tour_date = request.POST.get('tour_date', '')
        tour = Tour()
        tour.owner_id = user.pk
        tour.name = name
        tour.tour_date = tour_date
        tour.location = location
        tour.save()
        c = {'name':name, 'tour_date':tour_date, 'tour':tour}
        c.update(csrf(request))
        return render_to_response("myTours.html", c)

我是 django 新手,不知道问题出在哪里。

【问题讨论】:

    标签: django django-forms django-views csrf django-csrf


    【解决方案1】:

    您误解了如何处理 CSRF 令牌。您在 POST 上创建它,但重点是为 GET 请求上表单的原始显示创建它。中间件会在 POST 上检查,所以不需要添加。

    您应该按照 surfeurX 的建议使用 render 调用,但在调用时首先显示表单。

    【讨论】:

    • 什么意思?我不应该在模板中包含 csrf_token?
    • 我不明白你是如何从我所说的中得到的,也不明白如何使它更清楚。你有一些你没有显示的代码,它显示了用户在发布之前填写的表单。那就是需要 CSRF 令牌的代码。
    【解决方案2】:

    当我在 django 中实现表单时,我所做的是编写一个表单类并在视图中创建它的一个实例。然后将实例传递给模板。

    # form class eg. in models.py
    from django import forms
    
    class TourForm(forms.Form):
        name = forms.CharField(max_length=50)
    
    # in the view
    if request.method == 'POST':
        form = TourForm(request.POST)
        if form.is_valid():
            # do your stuff here with form data
    else:
        form = TourForm() # An unbound form
    
    return render(request, 'myTours.html', {
        'form': form,
    })
    

    在您的模板中,您可以像这样显示生成的表单:

    <form action="/mytours/" method="post">{% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Save" class="btn btn-primary" />
    </form>
    

    更多信息请查看官方django forms documentation

    【讨论】:

      【解决方案3】:

      你如何渲染你的模板???我认为您的 csrf_token 不会打印任何隐藏的输入,请在模板上下文中添加“请求”,例如:

      return render(request, "template.html", {"var": var})
      

      https://docs.djangoproject.com/en/dev/topics/http/shortcuts/#render

      【讨论】:

        【解决方案4】:

        您可能需要将 django.middleware.csrf.CsrfViewMiddleware 添加到 MIDDLEWARE_CLASSES 并将 RequestContext 添加到您的响应中:

        return render_to_response("myTours.html", c, context_instance=RequestContext(request))
        

        https://docs.djangoproject.com/en/1.3/ref/contrib/csrf/

        【讨论】:

        • “Django CSRF 验证失败。请求中止”可能是由中间件引发的。
        • @jpic,是的,我的错,你一定是对的,如果出现这个错误,中间件肯定存在,他可能只需要添加context_instance。
        猜你喜欢
        • 2015-03-08
        • 1970-01-01
        • 2014-02-03
        • 2016-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多