Как обрабатывать искаженный UUID python django rest-framework-api вместо 500?

При использовании неправильно сформированного UUID в django-rest-framework сервер выдает исключение и возвращает код состояния 500. Исключение ValueError «неправильно сформированная шестнадцатеричная строка UUID» не обрабатывается.

Разумнее обработать его правильно и вернуть код состояния 400.

Мне удалось сделать это с помощью собственного обработчика исключений, но это действительно грязное и уродливое решение.

Я думал о том, чтобы сделать это с помощью собственного сериализатора, но я не был уверен, как правильно с этим справиться и правильный ли это подход django.

Что вы думаете?

Ваше здоровье.


person Yaniv Peer    schedule 28.05.2017    source источник


Ответы (2)


Я решил эту проблему, переопределив ViewSet, поскольку он отвечает за получение объекта перед его передачей сериализатору. Для удобства я создал UUIDViewSetMixin, чтобы добавить его в нужные наборы представлений.

class UUIDViewSetMixin(object):
    lookup_field = 'id'

    def get_object(self):
        value = self.kwargs.get(self.lookup_field)
        try:
            uuid.UUID(value)
        except ValueError:
            result = {
                'code': 'bad_request',
                'message': _("'%(value)s' is not a valid uuid") % {'value', value}
            }
            return JsonResponse(data=data, request=status=status.HTTP_400_BAD_REQUEST)
        return super(UUIDViewSetMixin, self).get_object()
person Nour Wolf    schedule 28.05.2017
comment
Это была моя первая мысль, однако я бы предпочел более общее решение для всего проекта. - person Yaniv Peer; 30.07.2017

Добавление

lookup_value_regex = '[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}' 

к представлению использует проверку django, чтобы разрешить обработку только UUID, в противном случае он просто автоматически получает 404.

https://www.django-rest-framework.org/api-guide/routers/

Пример в документах:

class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    lookup_field = 'my_model_id'
    lookup_value_regex = '[0-9a-f]{32}'
person Felix    schedule 05.09.2019