feat: base 支持树型的递归分页查询以传with_children参数

This commit is contained in:
caoqianming 2024-11-07 17:50:48 +08:00
parent 8e08d37b62
commit c2a1ae661d
3 changed files with 30 additions and 1 deletions

View File

@ -179,6 +179,8 @@ class CustomListModelMixin(ListModelMixin):
@swagger_auto_schema(manual_parameters=[
openapi.Parameter(name="query", in_=openapi.IN_QUERY, description="定制返回数据",
type=openapi.TYPE_STRING, required=False),
openapi.Parameter(name="with_children", in_=openapi.IN_QUERY, description="带有children(yes/no/count)",
type=openapi.TYPE_STRING, required=False),
])
def list(self, request, *args, **kwargs):
"""

View File

@ -19,7 +19,30 @@ class GenSignatureSerializer(serializers.Serializer):
path = serializers.CharField(label="图片地址")
class CustomModelSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
class TreeSerializerMixin:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
request = self.context.get('request', None)
self.with_children = request.query_params.get('with_children', 'no') if request else 'no'
if self.with_children in ['yes', 'count']:
if 'children' not in self.fields:
self.fields['children'] = serializers.SerializerMethodField()
if 'children_count' not in self.fields:
self.fields['children_count'] = serializers.SerializerMethodField()
def get_children(self, obj):
if hasattr(obj, 'parent') and self.with_children == 'yes':
serializer_class = self.__class__
return serializer_class(obj.__class__.objects.filter(parent=obj), many=True, context=self.context).data
return []
def get_children_count(self, obj):
if hasattr(obj, 'parent') and self.with_children in ['yes', 'count']:
return obj.__class__.objects.filter(parent=obj).count()
return 0
class CustomModelSerializer(DynamicFieldsMixin, TreeSerializerMixin, serializers.ModelSerializer):
"""
自定义serializer/包含创建和新增字段处理
"""

View File

@ -102,6 +102,10 @@ class CustomGenericViewSet(MyLoggingMixin, GenericViewSet):
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
# 如果带有with_children查询, 出于优化需要应自动过滤掉一些内容
if (self.request.query_params.get("with_children", "no") in ["yes", "count"]
and self.request.query_params.get("parent", None) is None):
queryset = queryset.filter(parent=None)
# 用于性能优化
if self.select_related_fields:
queryset = queryset.select_related(*self.select_related_fields)