2👍
Rather than raising a ValidationError
, I will just raise a ParseError or another custom error that fits the error description:
from rest_framework import exceptions
def pre_delete(self, obj):
if obj.survey:
raise exceptions.ParseError("Too late to delete")
9👍
The solution I found was to override the destroy method on the 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)
For me makes much more sense to validate on the destroy method instead of validating on the object permission check as avances123 mentioned, since permission should only check for permission stuffs, and doesn’t return any messages related to validation.
Hope that helps 😉
- What is query.clone(), queryset.clone() for in django?
- In python django how do you print out an object's introspection? The list of all public methods of that object (variable and/or functions)?
- Creating UTF-8 JsonResponse in Django
- Django raises MultiValueDictKeyError in File Upload
- Django – Import views from separate apps
7👍
You can solve it with 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
Then add to your view’s permission_classes
from permissions import IsSurvey
class MyViewSet(viewsets.ModelViewSet):
permission_classes = (IsSurvey, )
- Celery beat not picking up periodic tasks
- Django: Check for related objects and whether it contains data
- Django OneToOneField with possible blank field
- Django how to override clean() method in a subclass of custom form?
- Django create new user without password
6👍
For anyone landing here since V3 like me… 🙂
You may now use perform_destroy
:
def perform_destroy(self, instance):
if not can_delete(instance):
raise ValidationError("You are not allowed to perform this action.")
instance.delete()
- Validating a Django model field based on another field's value?
- Django reverse error: NoReverseMatch
- Pycharm (Python IDE) doesn't auto complete Django modules
- How to create custom groups in django from group
- PIL – libjpeg.so.8: cannot open shared object file: No such file or directory
0👍
Update
validate doesn’t get called on delete.
Hmmm. Right yes. In that case I’d raise the exception in pre_delete
just as you are and override delete
to wrap the destroy
call in a try
block.
If you except ValidationError as e
you can use that to construct the response you want by hand…
return Response({"error" : e.message})
… or such.
You could probably populate self._errors
and leverage the existing error response behaviour but I can’t think how to do that off-hand.
I hope that helps.
First Answer (didn’t work):
Check the doc on Object Level Validation.
Implement validate
to check if the survey is set:
def validate(self, attrs):
if attrs['survey']
raise serializers.ValidationError("Too late to delete")
return attrs
If attrs
isn’t what you need here you’ll have to do something cleverer — but it will get your error in at the validation stage.
I hope that helps.
- Django render_to_string() ignores {% csrf_token %}
- How to have a link in label of a form field
- Is there a command for creating an app using cookiecutter-django?
- Django Newsletter App
- Django: Check for related objects and whether it contains data