Django CSRF验证失败。请求中止

时间:2012-12-20 12:04:22

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

我有一个模特:

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的新手,我不知道问题出在哪里。

4 个答案:

答案 0 :(得分:4)

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

您应该按照surfeurX的建议使用render来电,但是应该首先显示表单的来电。

答案 1 :(得分:1)

当我在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

答案 2 :(得分:0)

您可能需要将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/

答案 3 :(得分:0)

如何渲染模板???我认为你的csrf_token没有打印任何隐藏的输入,在模板上下文中添加“request”,如:

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

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