Django: Forbidden (CSRF cookie not set.): for DELETE request

Posted

技术标签:

【中文标题】Django: Forbidden (CSRF cookie not set.): for DELETE request【英文标题】: 【发布时间】:2022-01-12 21:17:32 【问题描述】:

概括地说,我的 GET、POST 和 PUT 请求都在工作。当我尝试 DELETE 请求时,我收到以下错误:"Forbidden (CSRF cookie not set.): /department/1 [07/Dec/2021 12:28:24]“删除 /department/1 HTTP/1.1”403 2870

我正在按照以下教程构建我的第一个 Angular/Python Django/SQLite 应用程序。到目前为止,我正在使用 Postman 处理所有请求。尚未构建角度部分。

由于我使用较新版本的 Django,存在一些差异。

https://www.youtube.com/watch?v=1Hc7KlLiU9w https://github.com/ArtOfEngineer/PythonDjangoAngular10/tree/master/DjangoAPI

我最多约 31 分钟

这是我在 virtualEnv 中的安装

asgiref==3.4.1 Django==4.0 django-cors-headers==3.10.1 djangorestframework==3.12.4 pytz==2021.3 - 我下面的例子没有安装这个。我需要让它运行 sqlparse==0.4.2 tzdata==2021.5

PracticeApp/views.py

#PracticeApp/views.py
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from rest_framework.parsers import JSONParser
from django.http.response import JsonResponse

from PracticeApp.models import Departments,
from PracticeApp.serializers import DepartmentSerializer

@csrf_exempt
def departmentApi(request, id=0):
    if request.method=='GET':
        departments = Departments.objects.all()
        departments_serializer = DepartmentSerializer(departments, many=True)
        return JsonResponse(departments_serializer.data, safe=False)

    elif request.method=='POST':
        department_data=JSONParser().parse(request)
        department_serializer = DepartmentSerializer(data=department_data)
        if department_serializer.is_valid():
            department_serializer.save()
            return JsonResponse("Added Successfully!!" , safe=False)
        return JsonResponse("Failed to Add.",safe=False)

    elif request.method=='PUT':
        department_data = JSONParser().parse(request)
        department=Departments.objects.get(DepartmentId=department_data['DepartmentId'])
        department_serializer=DepartmentSerializer(department,data=department_data)
        if department_serializer.is_valid():
            department_serializer.save()
            return JsonResponse("Updated Successfully!!", safe=False)
        return JsonResponse("Failed to Update.", safe=False)

    elif request.method=='DELETE':
        department=Departments.objects.get(DepartmentId=id)
        department.delete()
        return JsonResponse("Deleted Successfully!!", safe=False)

在 urls.py 你会看到我正在使用

从 django.urls 导入路径而不是 从 django.conf.urls 导入 url。

因此我使用 urlpatterns=[path()] 而不是 urlpatterns=[url()] 就像示例使用的那样

PracticeApp/urls.py

#PracticeApp/urls.py
from django.urls import path
from PracticeApp import views

urlpatterns=[
    path(r'department/',views.departmentApi),
    path(r'department/([0-9]+)',views.departmentApi), #delete method
] 

DjangoAPI/urls.py

#DjangoAPI/urls.py
from django.urls import include, path
from django.contrib import admin

urlpatterns = [
    path('admin/', admin.site.urls),
    path(r'', include('PracticeApp.urls'))
]

下面是settings.py中的相关sn-ps。

DjangoAPI/settings.py

#DjangoAPI/settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
    'PracticeApp.apps.PracticeappConfig',
    'rest_framework',
]

CORS_ORIGIN_ALLOW_ALL = True


MIDDLEWARE = [
    'corsheaders.middleware.CorsMiddleware',
    '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',
]

ROOT_URLCONF = 'DjangoAPI.urls'

PracticeApp/serializers.py

#PracticeApp/serializers.py
from rest_framework import serializers
from PracticeApp.models import Departments, Employees

class DepartmentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Departments
        fields = ('DepartmentId',
                  'DepartmentName')

【问题讨论】:

你能显示你提出删除请求的角度部分吗? 我现在只是在 Postman 中进行通话。 127.0.0.1:8000/department/1。不过,我现在注意到了一些事情。我之前在 PracticeApp/urls.py 文件中包含“+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)”。 (如果您导航到 EmployeeApp/urls.py 下的 github 存储库,您可以看到这一点。我删除了它,现在我得到了 Not Found: /department/1 错误。所以我认为该错误实际上不是 CSRF错误,而是我将 urlpatterns url() 切换为 path() 的问题 【参考方案1】:

您无法在视图中获取要删除的对象的 ID,并且您正在使用视图中指定的默认值为零。所以它找不到对象。更改您的删除网址如下:

 path(r'department/<int:department_id>',views.departmentApi)

在你看来:

department=Departments.objects.get(DepartmentId=department_id)

【讨论】:

我做出了改变。现在我得到了 Forbidden (CSRF cookie not set.): /department/1 我有一个语法错误并编辑了它。请尝试编辑后的代码,让我知道它是否有效。 现在可以了!非常感谢 不客气 :)

以上是关于Django: Forbidden (CSRF cookie not set.): for DELETE request的主要内容,如果未能解决你的问题,请参考以下文章

Django Admin登录403 Forbidden(未设置CSRF cookie。)

django 访问url报错Forbidden (CSRF cookie not set.): xxx 问

(转载)django 访问url报错Forbidden (CSRF cookie not set.): xxx 问

Django: Forbidden (CSRF cookie not set.): for DELETE request

django框架中form表单Post方法无法提交 Forbidden (403) CSRF verification failed. Request aborted.

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