Django Rest Framework: проверка перед удалением
Я хочу запустить проверку перед удалением объекта, чтобы предотвратить удаление в определенных случаях и вернуть как ошибку проверки. Как мне это сделать? То, что у меня сейчас, кажется неправильным:
class CallDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = XCall.objects.all()
serializer_class = CallSerializer
...
def pre_delete(self, obj):
if obj.survey:
raise serializers.ValidationError("Too late to delete")
4 ответов
решение, которое я нашел, было переопределить метод destroy в api.
class CallDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = XCall.objects.all()
serializer_class = CallSerializer
...
def destroy(self, request, *args, **kwargs):
obj = self.get_object()
if obj.survey:
return Response(data={'message': "Too late to delete"},
status=status.HTTP_400_BAD_REQUEST)
self.perform_destroy(obj)
return Response(status=status.HTTP_204_NO_CONTENT)
для меня имеет гораздо больше смысла проверять на уничтожить метод вместо проверки на проверку разрешений объекта, как avances123 упомянуто, так как разрешение должно проверять только для питания разрешений и не возвращает никаких сообщений, связанных с проверкой.
надеюсь, что это помогает ;)
вы можете решить его с permissions:
from rest_framework import permissions
class IsSurvey(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method == 'DELETE' and obj.survey:
return False
return True
затем добавьте в свой вид permission_classes
from permissions import IsSurvey
class MyViewSet(viewsets.ModelViewSet):
permission_classes = (IsSurvey, )
вместо того, чтобы поднимать ValidationError
, Я просто поднимаю ParseError или другая пользовательская ошибка, которая соответствует описанию ошибки:
from rest_framework import exceptions
def pre_delete(self, obj):
if obj.survey:
raise exceptions.ParseError("Too late to delete")
обновление
validate не вызывается при удалении.
Хммм. Да. В этом случае я бы поднял исключение в pre_delete
так же, как и вы, и переопределить delete
чтобы обернуть destroy
вызов в try
блок.
если вы except ValidationError as e
вы можете использовать это для создания ответа, который вы хотите вручную...
return Response({"error" : e.message})
... или такие.
вы, вероятно, могли бы заселить self._errors
и использовать существующую ошибку ответное поведение, но я не могу придумать, как это сделать.
надеюсь, это поможет.
первый ответ (не работает):
Проверьте doc на Проверка Уровня Объекта.
реализовать validate
чтобы проверить, установлен ли опрос:
def validate(self, attrs):
if attrs['survey']
raise serializers.ValidationError("Too late to delete")
return attrs
если attrs
это не то, что вам нужно здесь, вам придется сделать что - то умнее, но это приведет к вашей ошибке на этапе проверки.
Я надеюсь, что помогает.