Files
music-tag-web/component/drf/generics.py
2022-01-28 16:09:30 +08:00

67 lines
2.3 KiB
Python

# -*- coding: utf-8 -*-
"""
框架补充相关代码
"""
from django.http import Http404
from rest_framework import exceptions
from rest_framework.exceptions import PermissionDenied
from rest_framework.response import Response
from rest_framework.settings import api_settings
from rest_framework.views import set_rollback
from component.drf.mapping import exception_mapping
def exception_handler(exc, context):
"""
Returns the response that should be used for any given exception.
By default we handle the REST framework `APIException`, and also
Django's built-in `Http404` and `PermissionDenied` exceptions.
Any unhandled exceptions may return `None`, which will cause a 500 error
to be raised.
(Rewrite default method exception_handler)
"""
if isinstance(exc, Http404):
exc = exceptions.NotFound()
elif isinstance(exc, PermissionDenied):
exc = exceptions.PermissionDenied()
if isinstance(exc, exceptions.APIException):
headers = {}
if getattr(exc, "auth_header", None):
headers["WWW-Authenticate"] = exc.auth_header
if getattr(exc, "wait", None):
headers["Retry-After"] = "%d" % exc.wait
if isinstance(exc.detail, (list, dict)):
data = exc.detail
else:
data = {"detail": exc.detail}
set_rollback()
# code is added blow
exc_class_name = exc.__class__.__name__
if exc_class_name in exception_mapping:
message_list = []
# data type is in (list, dict)
if isinstance(data, dict):
for (k, v) in data.items():
if isinstance(v, list):
# remove 'non_field_errors' key name
if k in (api_settings.NON_FIELD_ERRORS_KEY, "detail"):
message_list.extend([str(i) for i in v])
else:
message_list.extend(["{0}: {1}".format(str(k), str(i)) for i in v])
else:
message_list.append(str(v))
elif isinstance(data, list):
message_list.extend([str(item) for item in data])
raise exception_mapping[exc_class_name](";".join(message_list))
else:
return Response(data, status=exc.status_code, headers=headers)
return None