Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRF validation - returns error 500 when error in Model.clean

I have the fields refundable and refundable_price in my model. I need to be sure that there is refundable_price not None in case refundable is True.

Since I want it everywhere, I've overridden SubOffer.clean method:

from django.core.exceptions import ValidationError

def save(self, **kwargs):
    self.full_clean()
    super().save(**kwargs)

def clean(self):
    super().clean()
    if self.refundable and self.refundable_price is None:
        raise ValidationError("V prípade refundovateľnej ponuky je nutné zadať sumu (je možné zadať aj 0)")

And I use ModelViewSet.

class SubOfferViewSet(ModelViewSet):
    serializer_class = SubOfferSerializer
    filterset_fields = {
        # 'approved_by': ['exact'],
        # 'approved_dt': ['gte', 'lte', 'gt', 'lt'],
    }

    def get_queryset(self):
        return SubOffer.objects.all()

The weird thing is that when I send POST to the ViewSet it returns 500 instead of JSON errors if there is an error in Suboffer.clean. Other errors work correctly.

It's the same when I use AJAX and when I use DRF API Viewer.

enter image description here

enter image description here How is that possible and how to make it work properly?

like image 356
Milano Avatar asked May 18 '26 07:05

Milano


1 Answers

A clean way that will handle all of your Validation errors (and any other errors you might want) is to have a custom EXCEPTION_HANDLER that converts the Django ValidationError to a DRF one.

See:

from django.core.exceptions import ValidationError as DjangoValidationError
from rest_framework.exceptions import ValidationError as DRFValidationError
from rest_framework.serializers import as_serializer_error
from rest_framework.views import exception_handler as drf_exception_handler


def exception_handler(exc, context):

    if isinstance(exc, DjangoValidationError):
        exc = DRFValidationError(as_serializer_error(exc))

    return drf_exception_handler(exc, context)


"""
In settings:

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'path.to_module.drf.exception_handler',
}
"""

Source: https://gist.github.com/twidi/9d55486c36b6a51bdcb05ce3a763e79f

A more in-depth example: https://github.com/HackSoftware/Django-Styleguide-Example/blob/9761c7592af553084e95bb5f8f9407a173aac66f/styleguide_example/api/exception_handlers.py

like image 160
Paul Onteri Avatar answered May 19 '26 22:05

Paul Onteri



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!