Як поширити помилку на методі create у серіалізаторі DRF?
Я намагаюся згенерувати помилку на основі деякої бізнес-логіки, як показано нижче
class ConsultationViewset(BaseModelViewset, ListModelViewsetMixin, RetrieveModelViewsetMixin, CreateModelViewsetMixin, UpdateModelViewsetMixin):
serializer_class = ConsultationSerializer
....
class ConsultationSerializer(serializers.ModelSerializer):
def create(self, validated_data):
consultation = ConsultationService.create_consultation(validated_data.pop('customer', None), validated_data)
return consultation
def create_consultation(customer: CustomerFactory.Models.CUSTOMER, validated_data):
if ticket is None:
raise exceptions.PermissionDenied("No active ticket found for this customer, request is forbidden")
Моя мета полягає у тому, щоб надіслати підняте повідомлення у create_consultation
у відповіді. Проте я продовжую отримувати AssertionError: create() did not return an object instance.
замість цього. Я міг би надіслати користувацьке повідомлення, якщо повторно підняти помилку у наборі даних, як показано нижче, але це неправильно, оскільки помилка має вигляд AssertionError.
class ConsultationViewset(...):
def perform_create(self, serializer):
try:
serializer.save()
except AssertionError as e:
raise exceptions.PermissionDenied('custom message')
Як правильно згенерувати помилку PermissionDenied
Когда вы используете Django REST Framework (DRF), метод serializers create() создаст и вернет новый объект. Ошибка возникает, как при вызове сериализатором функции
create_consultation, но запроса нет, и возникает ошибка. Из-за этой ошибки метод create() ничего не возвращает. Вот почему вы получаете AssertionError: create() did not return an object instance
Вы можете попробовать отловить ошибку в сериализаторе
class ConsultationSerializer(serializers.ModelSerializer):
def create(self, validated_data):
try:
consultation = ConsultationService.create_consultation(validated_data.pop('customer', None), validated_data)
return consultation
except exceptions.PermissionDenied as e:
raise e
except Exception as e:
# Convert other exceptions to DRF exceptions if needed
raise exceptions.ValidationError(str(e))
Вам не следует активировать PermissionDenied в методе create. это обрабатывается в представлении перед доступом к сериализатору. Итак, согласно документу разрешения, вам необходимо реализовать пользовательские разрешения и добавить их в классы разрешений в представлении.
from rest_framework import permissions
class CustomerAccessPermission(permissions.BasePermission):
message = 'No active ticket found for this customer, request is forbidden.'
def has_permission(self, request, view) -> bool:
return request.user.has_active_ticket() # example
class ExampleView(APIView):
def get_permissions(self) -> list[BasePermission]:
permission_classes = self.permission_classes
if self.request.method == "POST":
permission_classes = (
*permission_classes,
CustomerAccessPermission,
)
return [permission() for permission in permission_classes]