I have written a validate() function inside my serializer. By default, Serializer Errors return 400 as a status code. But I want to return 404. I tried this:
class MySerializer(serializers.ModelSerializer):
class Meta:
model = models.MyClass
fields = "__all__"
def validate(self, data):
current_user = self.context.get("request").user
user = data.get("user")
if user!=current_user:
raise ValidationError({'detail': 'Not found.'}, code=404)
return data
But it still returns 400 as a response in status code. How to do it?
You can do it from view by handling the serializes validation:
class MySerializer(serializers.ModelSerializer):
class Meta:
model = models.MyClass
fields = "__all__"
def validate(self, data):
current_user = self.context.get("request").user
user = data.get("user")
if user != current_user:
raise serializers.ValidationError(
{'detail': 'Not found.'},
code=404,
)
return data
class MyView(APIView):
def post(self, request):
serializer = MySerializer(
data=request.data,
context={'request': request},
)
if not serializer.is_valid():
return Response(serializer.errors, status=404)
return Response(serializer.data)
Alternately you can do it by defining own exception handler:
def my_exception_handler(exc, context):
response = exception_handler(exc, context)
if response is not None and response.status_code == 400:
response.status_code = 404
return response
class MyView(APIView):
exception_handler = my_exception_handler
def post(self, request):
serializer = MySerializer(
data=request.data,
context={'request': request},
)
serializer.is_valid(raise_exception=True)
return Response(serializer.data)
But as you said, if you want to do it from serializer, then you have to define custom exception and raise it from serialize :
class NotFoundError(serializers.ValidationError):
def __init__(self, detail):
super().__init__(detail, code=404)
class MySerializer(serializers.ModelSerializer):
class Meta:
model = models.MyClass
fields = "__all__"
def validate(self, data):
current_user = self.context.get("request").user
user = data.get("user")
if user != current_user:
raise NotFoundError({'detail': 'Not found.'})
return data