Django 1.11 - 尽管有csrf_token模板标签,但CSRF验证失败了

时间:2017-12-08 19:20:28

标签: python django

django的新手,制作待办事项列表页面。在输入文本框中输入文本并按ENTER键后,我收到CSRF错误。我知道这可能是重复的但是在阅读了很多论坛和文档之后我仍然会遇到这个问题。这是我尝试过的:

我的表单标记中有{% csrf_token %}模板标记。

我在设置的'django.middleware.csrf.CsrfViewMiddleware'部分有MIDDLEWARE

CSRF_COOKIE_SECURE = False是Django 1.11中的默认值。我使用的是http,而不是https。

我在视图中使用render()功能。

我的Firefox隐私设置已设置为允许第三方Cookie。在Chrome中也不起作用。

我没有在我的HTML enctype="text/plain"标记中使用form标记。

我尝试提供context dict来遵守release的摘录:

enter image description here

这是我的代码:

home.html的

<!DOCTYPE html>
<html>
    <head>
        <title>To-do List</title>
    </head>
    <body>
        <h1>To-do List</h1>
        <form method="POST"> <!--tried adding action="" as well-->
            <input name="item_text" id="id_new_item" placeholder="Enter a to-do list item" />
            {% csrf_token %}
        </form>
        <table id="id_table">
            <tr><td>{{ new_item_text }}</td></tr>
        </table>
    </body>
</html>

urls.py

from django.conf.urls import url
from django.contrib import admin
from lists import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.home_page, name='home')
]

settings.py

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

views.py

from django.shortcuts import render
from lists.models import Item

def home_page(request):
    if request.method == 'POST':
        Item.objects.create(text=request.POST['item_text'])
        return redirect('/')

    items = Item.objects.all()
    return render(request, 'lists/home.html', {'items': items}, {})

models.py

from django.db import models

class Item(models.Model):
    text = models.TextField(default='')

1 个答案:

答案 0 :(得分:0)

您也可以直接传递csrf令牌,而无需使用模板标记

from django.core.context_processors import csrf
from django.shortcuts import render


def home_page(request):
    c = {}
    c.update(csrf(request))

    if request.method == 'POST':
        Item.objects.create(text=request.POST['item_text'])
        return redirect('/')

    items = Item.objects.all()
    return render(request, 'lists/home.html', {'items': items, 
                                               'csrf':c})

在模板标签上,只需使用

即可
<input type='hidden' name='csrfmiddlewaretoken' value='{{csrf}}' />