【问题标题】:How to Dynamically set the fields of the Serializer (not during initialization)?如何动态设置序列化器的字段(不是在初始化期间)?
【发布时间】:2019-01-11 11:44:59
【问题描述】:

我正在尝试排除嵌套序列化程序的字段。我该怎么做?

例如,对于序列化程序

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)

【问题讨论】:

    标签: python django-rest-framework serialization


    【解决方案1】:

    好的,我在这里找到了解决方案: 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
    ])
    

    【讨论】:

      猜你喜欢
      • 2015-04-18
      • 2015-04-16
      • 2016-04-16
      • 2013-09-22
      • 2016-01-27
      • 2014-10-06
      • 1970-01-01
      • 2014-05-20
      • 1970-01-01
      相关资源
      最近更新 更多