45
You can raise different exceptions like:
from rest_framework.exceptions import APIException
from django.utils.encoding import force_text
from rest_framework import status
class CustomValidation(APIException):
status_code = status.HTTP_500_INTERNAL_SERVER_ERROR
default_detail = 'A server error occurred.'
def __init__(self, detail, field, status_code):
if status_code is not None:self.status_code = status_code
if detail is not None:
self.detail = {field: force_text(detail)}
else: self.detail = {'detail': force_text(self.default_detail)}
you can use this in your serializer like:
raise CustomValidation('Duplicate Username','username', status_code=status.HTTP_409_CONFLICT)
or
raise CustomValidation('Access denied','username', status_code=status.HTTP_403_FORBIDDEN)
17
By default, raising serializers.ValidationError
will return with HTTP_400_BAD_REQUEST
But sometimes we would like to return ValidationError
with normal 200
status code, because some libraries on the client side can’t parse json
response data while response code is not 200
.
I tried this. but it’s not worked:
raise serializers.ValidationError({'message':'Invalid email address'}, code=200)
So we can do this and it works:
res = serializers.ValidationError({'message':'Invalid email address'})
res.status_code = 200
raise res
- [Django]-Django: how does manytomanyfield with through appear in admin?
- [Django]-Getting Django admin url for an object
- [Django]-Django REST Framework upload image: "The submitted data was not a file"
4
Use django-rest-framework custom exception handler http://www.django-rest-framework.org/api-guide/exceptions/
def custom_exception_handler(exc, context=None):
response = exception_handler(exc, context)
if response is not None:
if response.data['detail'] == 'Duplicate Username':
response.data['username'] = response.data.pop('detail')
response.status_code = status.HTTP_409_CONFLICT
return response
- [Django]-How can I obtain the model's name or the content type of a Django object?
- [Django]-Get user information in django templates
- [Django]-Steps to Troubleshoot "django.db.utils.ProgrammingError: permission denied for relation django_migrations"
0
To add to Anush Devendra’s answer, it seems that raising anything else than a ValidationError
will bypass the treatment done by DRF on other fields.
Considering this code from DRF in exceptions.py:
def to_internal_value(self, data):
[...]
for field in fields:
[...]
try:
validated_value = field.run_validation(primitive_value)
if validate_method is not None:
validated_value = validate_method(validated_value)
except ValidationError as exc:
errors[field.field_name] = exc.detail
[...]
else:
set_value(ret, field.source_attrs, validated_value)
if errors:
raise ValidationError(errors)
return ret
If you want to have this kind of answer:
{
"my_first_field": [
"The first field had an error."
],
"my_second_field": [
"The second field had an error."
],
}
you need to raise a ValidationError
in the validate_<field>() methods.
Note that doing so you won’t be able to have a custom error heriting from ValidationError
and with a status_code
different of 400. Your detail
message will be extract and a new ValidationError
(with a default 400 status_code
) raise.
- [Django]-Django – installing mysqlclient error: mysqlclient 1.3.13 or newer is required; you have 0.9.3
- [Django]-Django admin TabularInline – is there a good way of adding a custom html column?
- [Django]-Django i18n: Make sure you have GNU gettext tools