定义一个可复用的mixin类:
class DynamicFieldsMinxin:
"""支持动态指定字段的序列化器,传参fields,序列化和反序列化都支持"""
Meta: type
def __init__(self, *args, **kwargs):
"""支持字段动态生成的序列化器,从默认的Meta.fields中过滤,无关字段不查不序列化"""
fields = kwargs.pop('fields', None)
super().__init__(*args, **kwargs)
if fields is not None:
allow = set(fields)
existing = set(self.fields)
for f in existing - allow:
self.fields.pop(f)
def __new__(cls, *args, **kwargs):
"""list序列化时,首先使用传参的fields,默认用meta.list_fields作为序列化字段"""
if kwargs.pop('many', False):
fields = getattr(cls.Meta, 'list_fields', None)
if fields and 'fields' not in kwargs:
kwargs['fields'] = fields
return cls.many_init(*args, **kwargs)
return super().__new__(cls, *args, **kwargs)
序列化器直接继承:
class BudgetSerializer(DynamicFieldsMinxin, serializers.ModelSerializer):
class Meta:
fields = "__all__"
model = models.Budget
使用:
serializer = self.get_serializer(page, many=True, fields=['id'])
在代码种体现如下:
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True, fields=['id'])
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)