我正在尝试排除嵌套序列化器的字段。我该怎么做?
例如,对于序列化器
class UserDetailSerializer(serializers.ModelSerializer):
user = UserSerializer() # want to exclude fields in this serializer
other = OtherSerializer()
class Meta:
model = User
它应该像
serialized = UserDetailSerializer(user_detail, exclude=['fields'])
并且排除值应传递到其他序列化程序,即UserSerializer和OtherSerializer。
我在drf文档中有一个DynamicFieldsModelSerializer的修改版,但它仅适用于从其继承的类。
class DynamicFieldsModelSerializer(serializers.ModelSerializer):
"""
A ModelSerializer that takes an additional `fields` argument that
controls which fields should be displayed.
"""
def __init__(self, *args, **kwargs):
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
exclude = kwargs.pop('exclude', None)
# Instantiate the superclass normally
super().__init__(*args, **kwargs)
if fields is not None:
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
existing = set(self.fields.keys())
for field_name in existing - allowed:
self.fields.pop(field_name)
elif exclude is not None:
# drop fields that are specified in the 'exclude' argument
for field_name in set(exclude):
self.fields.pop(field_name)
答案 0 :(得分:0)
好的,我在这里找到了解决方案: https://stackoverflow.com/a/37186932/10531996
这是经过编辑的版本,支持具有多个值的字段:
class NestedDynamicFieldsModelSerializer(serializers.ModelSerializer):
def __init__(self, *args, **kwargs):
def parse_nested_fields(fields):
field_object = {"fields": []}
for f in fields:
obj = field_object
nested_fields = f.split("__")
for v in nested_fields:
if v not in obj["fields"]:
obj["fields"].append(v)
if nested_fields.index(v) < len(nested_fields) - 1:
obj[v] = obj.get(v, {"fields": []})
obj = obj[v]
return field_object
def select_nested_fields(serializer, fields):
for k in fields:
if k == "fields":
fields_to_include(serializer, fields[k])
else:
select_nested_fields(serializer.fields[k], fields[k])
def fields_to_include(serializer, fields):
# Drop any fields that are not specified in the `fields` argument.
allowed = set(fields)
if isinstance(serializer, serializers.ListSerializer):
existing = set(serializer.child.fields.keys())
for field_name in existing - allowed:
serializer.child.fields.pop(field_name)
else:
existing = set(serializer.fields.keys())
for field_name in existing - allowed:
serializer.fields.pop(field_name)
# Don't pass the 'fields' arg up to the superclass
fields = kwargs.pop('fields', None)
# Instantiate the superclass normally
super(NestedDynamicFieldsModelSerializer, self).__init__(*args, **kwargs)
if fields is not None:
# import pdb; pdb.set_trace()
fields = parse_nested_fields(fields)
# Drop any fields that are not specified in the `fields` argument.
select_nested_fields(self, fields)
用法:
serialized = ClassSerializer(instance, fields=[
field,
field2__value1, field2__value2,
field3__field1__value1
])