Django 表单中的 CSRF 令牌丢失或不正确

Posted

技术标签:

【中文标题】Django 表单中的 CSRF 令牌丢失或不正确【英文标题】:CSRF token missing or incorrect in Django form 【发布时间】:2015-04-12 10:06:14 【问题描述】:

我对 Django 表单非常陌生。我试图简单地从文本字段中获取一个值并将其存储在数据库中。我收到一个错误报告:

*禁止 (403) CSRF 验证失败。 请求中止。 失败原因: CSRF 令牌丢失或不正确。

对于 POST 表单,您需要确保:

您的浏览器正在接受 cookie。

视图函数使用 RequestContext 作为模板,而不是 Context。

在模板中,每个 POST 表单内都有一个 % csrf_token % 模板标签,以内部 URL 为目标。

如果您没有使用 CsrfViewMiddleware,那么您必须在任何使用 csrf_token 模板标签的视图以及接受 POST 数据的视图上使用 csrf_protect。*

我哪里出错了?

我的views.py代码是:

from django.shortcuts import render
from feedback.models import Test
from mysite.forms import TestForm
from django.http import HttpResponse
from django.template import Context, loader

def test_view(request):
    form = TestForm
    t = loader.get_template('form.html')
    c = RequestContext(request,'n':'')
    if request.method=='POST':
        form = TestForm(request.POST)
        if form.is_valid():
            in_name = request.POST.get("firstname")
            fd = Test(name = in_name)
            fd.save()
    return HttpResponse(t.render(c))

我的models.py代码是:

from django.db import models
from django.forms import ModelForm

class Test(models.Model):
      name = models.CharField(max_length=255)

class TestForm(ModelForm):
      class Meta:
           model = Test
           fields = ['name']

我的 forms.py 代码是:

from django import forms

class TestForm(forms.Form):
      name = forms.CharField()

我的 HTML 模板是:

<!DOCTYPE html>
<html>
<head>
     <title>test form</title>
</head>

<body>

<form method = "POST">
% csrf_token %
First name:<br>
<input type="text" name="firstname" value =  n >
<br><br><br>
<input type="submit" value="Submit">
</form>
</body>

</html>

【问题讨论】:

【参考方案1】:

你这样做是错误的,非常 phpish。

将表单定义从models.py 移动到forms.py,因此您的feedback/forms.py 应该是:

from django.forms import ModelForm

class TestForm(forms.ModelForm):
      class Meta:
           model = Test
           fields = ['name']

feedback/views.py 应简化为:

from django.shortcuts import render, redirect

from feedback.forms import TestForm

def test_view(request):
    if request.method == 'POST':
        form = TestForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('.')
    else:
        form = TestForm()
    return render(request, 'form.html', 'form': form)

还有模板:

<!DOCTYPE html>
<html>
<head>
     <title>test form</title>
</head>

<body>

    <form method="POST">
        % csrf_token %
         form.as_p 
        <input type="submit" value="Submit">
    </form>

</body>

</html>

【讨论】:

以上是关于Django 表单中的 CSRF 令牌丢失或不正确的主要内容,如果未能解决你的问题,请参考以下文章

禁止(CSRF 令牌丢失或不正确。)Django

Django - 在同一个模板(ajax 和表单)中处理多个 CSRF 令牌禁止(CSRF 令牌丢失或不正确。)

Django - CSRF 令牌丢失或不正确

Django1.10 - /i18n/setlang/ CSRF 令牌丢失或不正确

CSRF 令牌丢失或不正确

CSRF 令牌丢失或不正确 - 在 Django 中使用自动完成灯