fix #I3V7NK 修复BUG(dvadmin): 新增 CustomMongoModelViewSet类重写get_serializer_class方法
parent
301f93cfd9
commit
7c7a26cf61
|
@ -1,7 +1,7 @@
|
||||||
"""
|
"""
|
||||||
Django settings for application project.
|
Django settings for application project.
|
||||||
|
|
||||||
Generated by 'django-admin startproject' using Django 1.11.21.
|
Generated by 'django-admin startproject' using Django 2.2.16.
|
||||||
|
|
||||||
For more information on this file, see
|
For more information on this file, see
|
||||||
https://docs.djangoproject.com/en/1.11/topics/settings/
|
https://docs.djangoproject.com/en/1.11/topics/settings/
|
||||||
|
|
|
@ -16,7 +16,6 @@ from . import mixins
|
||||||
from .filters import MongoSearchFilter, MongoOrderingFilter, AdvancedSearchFilter, MongoAdvancedSearchFilter
|
from .filters import MongoSearchFilter, MongoOrderingFilter, AdvancedSearchFilter, MongoAdvancedSearchFilter
|
||||||
from .generics import GenericAPIView
|
from .generics import GenericAPIView
|
||||||
from .logging.view_logger import CustomerModelViewLogger
|
from .logging.view_logger import CustomerModelViewLogger
|
||||||
from .pagination import Pagination
|
|
||||||
from .serializers import CustomModelSerializer
|
from .serializers import CustomModelSerializer
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,8 +172,122 @@ class MongoGenericAPIView(GenericAPIView):
|
||||||
|
|
||||||
|
|
||||||
class MongoGenericViewSet(ViewSetMixin, MongoGenericAPIView):
|
class MongoGenericViewSet(ViewSetMixin, MongoGenericAPIView):
|
||||||
pagination_class = Pagination
|
extra_filter_backends = []
|
||||||
pass
|
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
|
||||||
|
filter_backends = [DjangoFilterBackend, OrderingFilter, SearchFilter, AdvancedSearchFilter]
|
||||||
|
view_logger_classes = (CustomerModelViewLogger,)
|
||||||
|
|
||||||
|
def handle_logging(self, request: Request, *args, **kwargs):
|
||||||
|
view_loggers = self.get_view_loggers(request, *args, **kwargs)
|
||||||
|
for view_logger in view_loggers:
|
||||||
|
handle_action = getattr(view_logger, f'handle_{self.action}', None)
|
||||||
|
if handle_action and isinstance(handle_action, (FunctionType, MethodType)):
|
||||||
|
handle_action(request, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_serializer(self, *args, **kwargs):
|
||||||
|
serializer_class = self.get_serializer_class()
|
||||||
|
kwargs['context'] = self.get_serializer_context()
|
||||||
|
serializer = serializer_class(*args, **kwargs)
|
||||||
|
if isinstance(serializer, CustomModelSerializer):
|
||||||
|
serializer.request = self.request
|
||||||
|
return serializer
|
||||||
|
|
||||||
|
def filter_queryset(self, queryset):
|
||||||
|
for backend in set(set(self.filter_backends) | set(self.extra_filter_backends or [])):
|
||||||
|
queryset = backend().filter_queryset(self.request, queryset, self)
|
||||||
|
queryset = self.action_extra_filter_queryset(queryset)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def action_extra_filter_queryset(self, queryset):
|
||||||
|
action__extra_filter_backends = getattr(self, f"{self.action}_extra_filter_backends", None)
|
||||||
|
if not action__extra_filter_backends:
|
||||||
|
return queryset
|
||||||
|
for backend in action__extra_filter_backends:
|
||||||
|
queryset = backend().filter_queryset(self.request, queryset, self)
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
def get_serializer_class(self):
|
||||||
|
action_serializer_name = f"{self.action}_serializer_class"
|
||||||
|
action_serializer_class = getattr(self, action_serializer_name, None)
|
||||||
|
if action_serializer_class:
|
||||||
|
return action_serializer_class
|
||||||
|
return super().get_serializer_class()
|
||||||
|
|
||||||
|
def reverse_action(self, url_name, *args, **kwargs):
|
||||||
|
return super().reverse_action(url_name, *args, **kwargs)
|
||||||
|
|
||||||
|
def get_action_extra_permissions(self):
|
||||||
|
"""
|
||||||
|
获取已配置的action权限校验,并且实例化其对象
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
action_extra_permission_classes = getattr(self, f"{self.action}_extra_permission_classes", None)
|
||||||
|
if not action_extra_permission_classes:
|
||||||
|
return []
|
||||||
|
return [permission() for permission in action_extra_permission_classes]
|
||||||
|
|
||||||
|
def check_action_extra_permissions(self, request):
|
||||||
|
"""
|
||||||
|
逐个校验action权限校验
|
||||||
|
:param request:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
for permission in self.get_action_extra_permissions():
|
||||||
|
if not permission.has_permission(request, self):
|
||||||
|
self.permission_denied(
|
||||||
|
request, message=getattr(permission, 'message', None)
|
||||||
|
)
|
||||||
|
|
||||||
|
def check_action_extra_object_permissions(self, request, obj):
|
||||||
|
"""
|
||||||
|
action方法的专属对象权限校验
|
||||||
|
:param request:
|
||||||
|
:param obj:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
for permission in self.get_action_extra_permissions():
|
||||||
|
if not permission.has_object_permission(request, self, obj):
|
||||||
|
self.permission_denied(
|
||||||
|
request, message=getattr(permission, 'message', None)
|
||||||
|
)
|
||||||
|
|
||||||
|
def initial(self, request, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
重写initial方法
|
||||||
|
(1)新增action的权限校验
|
||||||
|
:param request:
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
super().initial(request, *args, **kwargs)
|
||||||
|
self.check_action_extra_permissions(request)
|
||||||
|
|
||||||
|
def get_object(self):
|
||||||
|
queryset = self.filter_queryset(self.get_queryset())
|
||||||
|
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
|
||||||
|
assert lookup_url_kwarg in self.kwargs, (
|
||||||
|
'Expected view %s to be called with a URL keyword argument '
|
||||||
|
'named "%s". Fix your URL conf, or set the `.lookup_field` '
|
||||||
|
'attribute on the view correctly.' %
|
||||||
|
(self.__class__.__name__, lookup_url_kwarg)
|
||||||
|
)
|
||||||
|
filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]}
|
||||||
|
obj = get_object_or_404(queryset, **filter_kwargs)
|
||||||
|
self.check_object_permissions(self.request, obj)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def check_object_permissions(self, request, obj):
|
||||||
|
"""
|
||||||
|
重新check_object_permissions
|
||||||
|
(1)新增action方法的专属对象权限检查入口
|
||||||
|
(2)先校验共同的object_permissions, 再校验action的object_permissions
|
||||||
|
:param request:
|
||||||
|
:param obj:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
super().check_object_permissions(request, obj)
|
||||||
|
self.check_action_extra_object_permissions(request, obj)
|
||||||
|
|
||||||
|
|
||||||
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
|
class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
|
||||||
|
|
Loading…
Reference in New Issue