mirror of
https://github.com/HackSoftware/Django-Styleguide.git
synced 2024-11-22 01:26:43 +03:00
61 lines
1.7 KiB
Python
61 lines
1.7 KiB
Python
from rest_framework import serializers
|
|
from rest_framework import exceptions as rest_exceptions
|
|
|
|
from django.core.exceptions import ValidationError
|
|
|
|
|
|
def create_serializer_class(name, fields):
|
|
return type(name, (serializers.Serializer, ), fields)
|
|
|
|
|
|
def inline_serializer(*, fields, data=None, **kwargs):
|
|
serializer_class = create_serializer_class(name='', fields=fields)
|
|
|
|
if data is not None:
|
|
return serializer_class(data=data, **kwargs)
|
|
|
|
return serializer_class(**kwargs)
|
|
|
|
|
|
def get_first_matching_attr(obj, *attrs, default=None):
|
|
for attr in attrs:
|
|
if hasattr(obj, attr):
|
|
return getattr(obj, attr)
|
|
|
|
return default
|
|
|
|
|
|
def get_error_message(exc):
|
|
if hasattr(exc, 'message_dict'):
|
|
return exc.message_dict
|
|
error_msg = get_first_matching_attr(exc, 'message', 'messages')
|
|
|
|
if isinstance(error_msg, list):
|
|
error_msg = ', '.join(error_msg)
|
|
|
|
if error_msg is None:
|
|
error_msg = str(exc)
|
|
|
|
return error_msg
|
|
|
|
|
|
class ExceptionHandlerMixin:
|
|
"""
|
|
Mixin that transforms Django and Python exceptions into rest_framework ones.
|
|
without the mixin, they return 500 status code which is not desired.
|
|
"""
|
|
expected_exceptions = {
|
|
ValueError: rest_exceptions.ValidationError,
|
|
ValidationError: rest_exceptions.ValidationError,
|
|
PermissionError: rest_exceptions.PermissionDenied
|
|
}
|
|
|
|
def handle_exception(self, exc):
|
|
if isinstance(exc, tuple(self.expected_exceptions.keys())):
|
|
drf_exception_class = self.expected_exceptions[exc.__class__]
|
|
drf_exception = drf_exception_class(get_error_message(exc))
|
|
|
|
return super().handle_exception(drf_exception)
|
|
|
|
return super().handle_exception(exc)
|