列出Django Rest Framework序列化程序中必填字段的名称(并忽略父字段)

我想做的是获取序列化器中所有字段的列表,

  • 不要包含required=False作为参数。
  • 不来自父级序列化程序。

例如,如果我有以下序列化器:

class ParentSerializer(serializers.Serializer):
    parent_field = serializers.IntegerField

class ChildSerializer(ParentSerializer):
    child_field_required = serializers.IntegerField
    child_field_not_required = serializers.IntegerField(required=False) 

我希望结果输出为:

['child_field_required']

我发现我可以得到一个声明字段的有序列表,例如:

self.get_serializer().get_fields()
>> OrderedDict([
       ('parent_field',IntegerField()),('child_field_required',('child_field_not_required',IntegerField(required=False)),])

但是我无法越过这一步。

ksf0204ksf 回答:列出Django Rest Framework序列化程序中必填字段的名称(并忽略父字段)

serializers.Serializer继承时,必须在类主体上显式声明所有字段(与serializers.ModelSerializer遍历模型层以自动生成字段不同)。在这种情况下,您可以执行以下操作:

parent_field_names = {
    name
    for base in type(instance).__bases__
    if hasattr(base,'_declared_fields')
    for name in base._declared_fields
}
desired_fields = [
    (name,field)
    for name,field in instance.get_fields().items()
    if name not in parent_field_names and
    field._kwargs.get('required',None) is not False
]

假设instance是一个serializers.Serializer实例。 parent_field_names是指用于O(1)查找的集合。

以上内容取决于几个实施细节

  • serializers.Serializer-serializers.SerializerMetaclass的元类将声明的字段分配为类属性_declared_fields字典
  • 在整个构建过程(__new__中,serializers.Field类将最初传递的关键字参数保留为实例上新创建的字段实例的_kwargs属性

注释:

,

我想出了一个解决方案,但是我觉得那里有一个更优雅的解决方案...

instance = ChildSerializer()

serializer_fields = instance.get_fields()
parent_serializer_fields = instance.__class__.__bases__[0]().get_fields()
child_fields = {k: serializer_fields[k] for k in set(serializer_fields) - set(parent_serializer_fields)}
required_fields = [k for k,v in child_fields.items() if v.required]
本文链接:https://www.f2er.com/3020431.html

大家都在问