Django Rest Framework RetrieveUpdateAPIView не работает
У меня возникла проблема с использованием RetrieveUpdateAPIView и RetrieveDestroyAPIView. Я пытаюсь обновить или удалить объект Newsletter, будучи зарегистрированным как администратор. К сожалению, после нажатия 'PUT' или 'DELETE' меня автоматически выкидывает из системы, а Django Rest Framework выдает ошибку:
{
"detail": "CSRF Failed: CSRF token missing."
}
Postman также выдает ошибку:
{
"detail": "Authentication credentials were not provided."
}
Код ниже:
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",
]
REST_FRAMEWORK = {
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
"PAGE SIZE": 10,
"DEFAULT_FILTER_BACKENDS": [
"django_filters.rest_framework.DjangoFilterBackend",
],
}
serializers.py
from rest_framework import serializers
from core.models import Newsletter
import re
class NewsletterSerializer(serializers.ModelSerializer):
class Meta:
model = Newsletter
fields = "__all__"
extra_kwargs = {
"created_at": {
"format": "%Y-%m-%d %H:%M:%S",
}
}
class NewsletterCreateSerializer(serializers.ModelSerializer):
email = serializers.CharField(
required=False,
allow_blank=True,
)
class Meta:
model = Newsletter
fields = [
"id",
"created_at",
"email",
]
extra_kwargs = {
"created_at": {
"format": "%Y-%m-%d %H:%M:%S",
"read_only": True,
},
}
def validate_email(self, email):
print(email)
if email == "":
raise serializers.ValidationError(
detail="E-mail Address is required.",
)
if email and not re.match(pattern=r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)", string=email):
raise serializers.ValidationError(
detail="The e-mail address format is invalid.",
)
if self.instance is None:
if email and re.match(pattern=r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)",
string=email) and Newsletter.objects.filter(email=email).exists():
raise serializers.ValidationError(
detail="The newsletter already exists.",
)
else:
if self.instance.email != email and Newsletter.objects.filter(email=email).exists():
raise serializers.ValidationError(
detail="The newsletter already exists.",
)
return email
views.py
class NewsletterAPIView(ListAPIView):
filter_backends = [DjangoFilterBackend, OrderingFilter]
ordering_fields = ["created_at", "email"]
def get_view_name(self):
return "API Newsletters"
def get_queryset(self):
return Newsletter.objects.all()
def get_serializer_class(self):
return NewsletterSerializer
class NewsletterUpdateAPIView(RetrieveUpdateAPIView):
def get_queryset(self):
print('queryset')
return Newsletter.objects.all()
def get_serializer_class(self):
return NewsletterCreateSerializer
def update(self, request, *args, **kwargs):
print('update')
instance = self.get_object()
serializer = self.get_serializer(data=request.data, instance=instance)
if serializer.is_valid():
print('is valid')
self.perform_update(serializer=serializer)
return Response(
data={
"message": "The newsletter has been updated successfully.",
"data": serializer.data,
"updated_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"updated_by": self.request.user.username,
},
status=status.HTTP_200_OK,
)
else:
print('not valid')
return Response(
data=serializer.errors,
status=status.HTTP_400_BAD_REQUEST,
)
class NewsletterDeleteAPIView(RetrieveDestroyAPIView):
def get_queryset(self):
return Newsletter.objects.all()
def get_serializer_class(self):
return NewsletterSerializer
def delete(self, request, *args, **kwargs):
print(self.headers)
instance = self.get_object()
id, created_at, email = instance.id, instance.created_at, instance.email
try:
self.perform_destroy(instance=instance)
return Response(
data={
"message": f"The newsletter {email} has been deleted successfully.",
"data": {
"id": id,
"created_at": created_at.strftime("%Y-%m-%d %H:%M:%S"),
"email": email,
},
"deleted_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"deleted_by": self.request.user.username,
},
status=status.HTTP_204_NO_CONTENT,
)
except Exception:
return Response(
data={
"An error occurred while deleting the object, please try again."
},
status=status.HTTP_400_BAD_REQUEST,
)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path(
route="api/v1/newsletters",
view=views.NewsletterAPIView.as_view(),
name="api-v1-newsletters",
),
path(
route="api/v1/newsletters/update/<int:pk>",
view=views.NewsletterUpdateAPIView.as_view(),
name="api-v1-newsletters-update",
),
path(
route="api/v1/newsletters/delete/<int:pk>",
view=views.NewsletterDeleteAPIView.as_view(),
name="api-v1-newsletters-delete",
),
]
Не реализован метод аутентификации. Кроме того, метод def_update в классе NewsletterUpdateAPIView и метод def_delete в классе NewsletterDeleteAPIView не выполняются вообще.
В консоли браузера в разделе "Приложение" в Cookies есть CSRF-токен.