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)