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

At a high level, my GET, POST, and PUT requests are all working. When I try a DELETE request, I get a following error: "Forbidden (CSRF cookie not set.): /department/1 [07/Dec/2021 12:28:24] "DELETE /department/1 HTTP/1.1" 403 2870

I'm following the follow tutorial to build my first Angular/Python Django/SQLite app. I'm using Postman for all the requests so far. No angular portion built yet.

There have been a few discrepancies due to me using newer versions of Django.

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

I'm up to about ~31 minutes

Here are my installations in my virtualEnv

  • asgiref==3.4.1
  • Django==4.0
  • django-cors-headers==3.10.1
  • djangorestframework==3.12.4
  • pytz==2021.3 - the example I'm following didn't install this. I needed to though get it to run
  • 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)

in the urls.py you'll see that I'm using

  • from django.urls import path instead of
  • from django.conf.urls import url.

Therefore I'm using urlpatterns=[path()] instead of urlpatterns=[url()] like the example uses

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'))
]

below are the relevant snippets from the settings.py.

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')

You can not get the ID of object to be deleted in your view and you are using the default value specified in the view that is zero. So it can not find the object. Change your delete url as follow:

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

And in your view:

department=Departments.objects.get(DepartmentId=department_id)
Back to Top