feat: base 独立出ComplexQueryMixin

This commit is contained in:
caoqianming 2025-05-26 13:23:32 +08:00
parent ed6b6c2776
commit d385fefc4f
2 changed files with 48 additions and 38 deletions

View File

@ -16,6 +16,8 @@ from rest_framework.generics import get_object_or_404
from drf_yasg.utils import swagger_auto_schema from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi from drf_yasg import openapi
from apps.utils.serializers import PkSerializer from apps.utils.serializers import PkSerializer
from rest_framework.decorators import action
from apps.utils.serializers import ComplexSerializer
# 实例化myLogger # 实例化myLogger
myLogger = logging.getLogger('log') myLogger = logging.getLogger('log')
@ -221,6 +223,47 @@ class CustomListModelMixin(ListModelMixin):
""" """
return data return data
class ComplexQueryMixin:
"""复杂查询
"""
@swagger_auto_schema(request_body=ComplexSerializer, responses={200: {}})
@action(methods=['post'], detail=False, perms_map={'post': '*'})
def cquery(self, request):
"""复杂查询
复杂查询
"""
sr = ComplexSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
queryset = self.filter_queryset(self.get_queryset())
new_qs = queryset.none()
try:
for m in vdata.get('querys', []):
one_qs = queryset
for n in m:
st = {}
if n['compare'] == '!': # 如果是排除比较式
st[n['field']] = n['value']
one_qs = one_qs.exclude(**st)
elif n['compare'] == '':
st[n['field']] = n['value']
one_qs = one_qs.filter(**st)
else:
st[n['field'] + '__' + n['compare']] = n['value']
one_qs = one_qs.filter(**st)
new_qs = new_qs | one_qs
except Exception as e:
raise ParseError(str(e))
page = self.paginate_queryset(new_qs)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(new_qs, many=True)
return Response(serializer.data)
class MyLoggingMixin(object): class MyLoggingMixin(object):
"""Mixin to log requests""" """Mixin to log requests"""

View File

@ -10,7 +10,8 @@ from rest_framework.viewsets import GenericViewSet
from apps.system.models import DataFilter, Dept from apps.system.models import DataFilter, Dept
from apps.utils.mixins import (MyLoggingMixin, BulkCreateModelMixin, BulkUpdateModelMixin, from apps.utils.mixins import (MyLoggingMixin, BulkCreateModelMixin, BulkUpdateModelMixin,
BulkDestroyModelMixin, CustomListModelMixin, CustomRetrieveModelMixin) BulkDestroyModelMixin, CustomListModelMixin,
CustomRetrieveModelMixin, ComplexQueryMixin)
from apps.utils.permission import ALL_PERMS, RbacPermission, get_user_perms_map from apps.utils.permission import ALL_PERMS, RbacPermission, get_user_perms_map
from apps.utils.queryset import get_child_queryset2, get_child_queryset_u from apps.utils.queryset import get_child_queryset2, get_child_queryset_u
from apps.utils.serializers import ComplexSerializer from apps.utils.serializers import ComplexSerializer
@ -187,44 +188,10 @@ class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
return queryset return queryset
return queryset.filter(create_by=self.request.user) return queryset.filter(create_by=self.request.user)
class CustomModelViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomListModelMixin, class CustomModelViewSet(BulkCreateModelMixin, BulkUpdateModelMixin, CustomListModelMixin,
CustomRetrieveModelMixin, BulkDestroyModelMixin, CustomGenericViewSet): CustomRetrieveModelMixin, BulkDestroyModelMixin, ComplexQueryMixin, CustomGenericViewSet):
""" """
增强的ModelViewSet 增强的ModelViewSet
""" """
pass
@swagger_auto_schema(request_body=ComplexSerializer, responses={200: {}})
@action(methods=['post'], detail=False, perms_map={'post': '*'})
def cquery(self, request):
"""复杂查询
复杂查询
"""
sr = ComplexSerializer(data=request.data)
sr.is_valid(raise_exception=True)
vdata = sr.validated_data
queryset = self.filter_queryset(self.get_queryset())
new_qs = queryset.none()
try:
for m in vdata.get('querys', []):
one_qs = queryset
for n in m:
st = {}
if n['compare'] == '!': # 如果是排除比较式
st[n['field']] = n['value']
one_qs = one_qs.exclude(**st)
elif n['compare'] == '':
st[n['field']] = n['value']
one_qs = one_qs.filter(**st)
else:
st[n['field'] + '__' + n['compare']] = n['value']
one_qs = one_qs.filter(**st)
new_qs = new_qs | one_qs
except Exception as e:
raise ParseError(str(e))
page = self.paginate_queryset(new_qs)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(new_qs, many=True)
return Response(serializer.data)