【问题标题】:How to get all instances in serializer method field如何获取序列化方法字段中的所有实例
【发布时间】:2020-02-28 05:52:33
【问题描述】:

如何获取序列化方法字段中的所有实例

我有一个序列化器方法字段,我正在将列表数据以上下文的形式传递给序列化器,如下所示。

name_list = [ "abc", "def",....]
obj_list = abc.objects.all() 

Serializer = abcSerializer (obj_list, context=name_list, many=True)

    class abcSerializer (serializers.ModelSerializer):
        xyz = serializers.SerializerMethodField ("getXYZ", read_only=True)

        class Meta:
            model = abc

            def getXYZ (self, data):
                # here I want all instanceses, but I got only one instance in data. 

我想将 name_list 数据一一附加到具有相同索引的实例数据? 如何在我的序列化方法字段中获取所有实例?

【问题讨论】:

  • self.context ?
  • @ArakkalAbu self.context 是 name_list,我传递给序列化程序以将名称附加到实例数据的名称列表。

标签: python django django-rest-framework serialization


【解决方案1】:

为什么需要所有实例?如果您想在所有情况下操作某些东西,最好在将其作为参数传递给 Serializer 之前执行此操作。如果要获取单个实例,则应获取data 参数中的值。但是你的缩进是错误的。试试这样:

class abcSerializer (serializers.ModelSerializer):
    xyz = serializers.SerializerMethodField("getXYZ")

    class Meta:
       model = abc

    def getXYZ(self, data):
       print(data) # it will print a instance of abc
       return value_based_on_data

更新

那我觉得你应该这样试试:

第一次更新序列化器类:

class abcSerializer (serializers.ModelSerializer):  # use PascalCase for naming classes
    xyz = serializers.ReadOnlyField()

    class Meta:
        model = abc
        fields = '__all__'   # use PascalCase for naming classes

然后使用以下代码获取xyz的值:

obj_list = []
for i, item in enumerate(abc.objects.all()):
    item.xyz = name_list[i]
    obj_list.append(item)

abcSerializer(obj_list, many=True).data

【讨论】:

  • 感谢@ruddra 提出正确的缩进建议,正如您指出的那样,我编辑了我的问题。我想用我在序列化程序上下文中传递的 name_list 数据填充 xyz 字段,其顺序与作为数据传递给此方法字段的对象的顺序相同。
  • 谢谢@ruddra,你是对的,你的方法适用于附加数据,以防我想将数据附加到模型的所有实例,但我只想附加我的序列化字段,因为模型没有 xyz场地。我的序列化程序在此方法中有方法字段名称 getXYZ,我需要您在序列化程序中传递的 obj_list。
  • 这就是我在这里所做的。但是为什么要在序列化器方法字段中这样做,而这显然不是一个优化的解决方案?
  • 谢谢@ruddra,你是对的,我以未优化的方式进行操作,我改变了工作方式。
【解决方案2】:

在深入研究调试之后,我意识到我应该与社区分享我的发现。 Look at the below line:

Serializer = abcSerializer (obj_list, context=name_list, many=True)

这里 many=True 将 abcSerializer 设置为列表序列化器,根据列表序列化器中的rest framework documentation,我们可以在更新方法中访问查询集的所有对象,如下所示

    class BookListSerializer(serializers.ListSerializer):
        def update(self, instance, validated_data):
            # Maps for id->instance and id->data item.
            book_mapping = {book.id: book for book in instance}
            data_mapping = {item['id']: item for item in validated_data}

            # Perform creations and updates.

我发现即使在serializerMethodField 中,我们也可以使用以下语法以任何方法访问查询集的所有对象

def getXYZ (self, data):
    objects = self.instance

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-22
    相关资源
    最近更新 更多