102 lines
3.6 KiB
Python
102 lines
3.6 KiB
Python
![]() |
import logging
|
||
|
import traceback
|
||
|
from types import FunctionType, MethodType
|
||
|
|
||
|
from rest_framework.exceptions import APIException as DRFAPIException
|
||
|
from rest_framework.request import Request
|
||
|
from rest_framework.views import APIView
|
||
|
|
||
![]() |
from ..utils import exceptions
|
||
|
from ..utils.model_util import ModelRelateUtils
|
||
![]() |
from .logging.view_logger import CustomerRelationshipViewLogger
|
||
|
from .response import SuccessResponse, ErrorResponse
|
||
|
from .serializers import CustomModelSerializer
|
||
|
|
||
|
logger = logging.getLogger(__name__)
|
||
|
|
||
|
|
||
|
def op_exception_handler(ex, context):
|
||
|
"""
|
||
|
统一异常拦截处理
|
||
|
目的:(1)取消所有的500异常响应,统一响应为标准错误返回
|
||
|
(2)准确显示错误信息
|
||
|
:param ex:
|
||
|
:param context:
|
||
|
:return:
|
||
|
"""
|
||
|
msg = ''
|
||
|
if isinstance(ex, DRFAPIException):
|
||
|
# set_rollback()
|
||
|
msg = ex.detail
|
||
|
elif isinstance(ex, exceptions.APIException):
|
||
|
msg = ex.message
|
||
|
elif isinstance(ex, Exception):
|
||
|
logger.error(traceback.format_exc())
|
||
|
msg = str(ex)
|
||
|
return ErrorResponse(msg=msg)
|
||
|
|
||
|
|
||
|
class CustomAPIView(APIView):
|
||
|
"""
|
||
|
继承、增强DRF的APIView
|
||
|
"""
|
||
|
extra_permission_classes = ()
|
||
|
# 仅当GET方法时会触发该权限的校验
|
||
|
GET_permission_classes = ()
|
||
|
|
||
|
# 仅当POST方法时会触发该权限的校验
|
||
|
POST_permission_classes = ()
|
||
|
|
||
|
# 仅当DELETE方法时会触发该权限的校验
|
||
|
DELETE_permission_classes = ()
|
||
|
|
||
|
# 仅当PUT方法时会触发该权限的校验
|
||
|
PUT_permission_classes = ()
|
||
|
|
||
|
view_logger_classes = ()
|
||
|
|
||
|
def initial(self, request: Request, *args, **kwargs):
|
||
|
super().initial(request, *args, **kwargs)
|
||
|
self.check_extra_permissions(request)
|
||
|
self.check_method_extra_permissions(request)
|
||
|
|
||
|
def get_view_loggers(self, request: Request, *args, **kwargs):
|
||
|
logger_classes = self.view_logger_classes or []
|
||
|
if not logger_classes:
|
||
|
return []
|
||
|
view_loggers = [logger_class(view=self, request=request, *args, **kwargs) for logger_class in logger_classes]
|
||
|
return view_loggers
|
||
|
|
||
|
def handle_logging(self, request: Request, *args, **kwargs):
|
||
|
view_loggers = self.get_view_loggers(request, *args, **kwargs)
|
||
|
method = request.method.lower()
|
||
|
for view_logger in view_loggers:
|
||
|
view_logger.handle(request, *args, **kwargs)
|
||
|
logger_fun = getattr(view_logger, f'handle_{method}', None)
|
||
|
if logger_fun and isinstance(logger_fun, (FunctionType, MethodType)):
|
||
|
logger_fun(request, *args, **kwargs)
|
||
|
|
||
|
def get_extra_permissions(self):
|
||
|
return [permission() for permission in self.extra_permission_classes]
|
||
|
|
||
|
def check_extra_permissions(self, request: Request):
|
||
|
for permission in self.get_extra_permissions():
|
||
|
if not permission.has_permission(request, self):
|
||
|
self.permission_denied(
|
||
|
request, message=getattr(permission, 'message', None)
|
||
|
)
|
||
|
|
||
|
def get_method_extra_permissions(self):
|
||
|
_name = self.request.method.upper()
|
||
|
method_extra_permission_classes = getattr(self, f"{_name}_permission_classes", None)
|
||
|
if not method_extra_permission_classes:
|
||
|
return []
|
||
|
return [permission() for permission in method_extra_permission_classes]
|
||
|
|
||
|
def check_method_extra_permissions(self, request):
|
||
|
for permission in self.get_method_extra_permissions():
|
||
|
if not permission.has_permission(request, self):
|
||
|
self.permission_denied(
|
||
|
request, message=getattr(permission, 'message', None)
|
||
|
)
|