fix #I3V7NK 修复BUG(dvadmin): 新增 CustomMongoModelViewSet类重写get_serializer_class方法
parent
301f93cfd9
commit
7c7a26cf61
|
@ -1,7 +1,7 @@
|
|||
"""
|
||||
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
|
||||
https://docs.djangoproject.com/en/1.11/topics/settings/
|
||||
|
|
|
@ -16,7 +16,6 @@ from . import mixins
|
|||
from .filters import MongoSearchFilter, MongoOrderingFilter, AdvancedSearchFilter, MongoAdvancedSearchFilter
|
||||
from .generics import GenericAPIView
|
||||
from .logging.view_logger import CustomerModelViewLogger
|
||||
from .pagination import Pagination
|
||||
from .serializers import CustomModelSerializer
|
||||
|
||||
|
||||
|
@ -173,8 +172,122 @@ class MongoGenericAPIView(GenericAPIView):
|
|||
|
||||
|
||||
class MongoGenericViewSet(ViewSetMixin, MongoGenericAPIView):
|
||||
pagination_class = Pagination
|
||||
pass
|
||||
extra_filter_backends = []
|
||||
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,
|
||||
|
|
Loading…
Reference in New Issue