【问题标题】:django serialize and deserialize object with SerializerMethodFielddjango 使用 SerializerMethodField 序列化和反序列化对象
【发布时间】:2019-11-03 02:24:57
【问题描述】:

我正在使用 djangorestframework 3.7.7

我有不包含“所有者”字段的“项目”模型。 项目模型序列化器看起来像这样:

class ItemSerializer(serializers.ModelSerializer):
    id = serializers.CharField(required=False, max_length=1000, allow_null=True)
    owner = serializers.SerializerMethodField()
    class Meta:
        model = Item

    fields = [
        'id',
        'owner'
    ]

    def get_owner(self, item):
        return item.package.owner if item.package else None

当使用序列化它时:

ser_item = ItemSerializer(item)

我在ser_item.data 中获得了owner 字段

但是在反序列化的时候,使用:

serializer = ItemSerializer(data=ser_item)
serializer.is_valid(raise_exception=True)
obj = Item(**serializer.validated_data)

obj 不包含 owner 字段。 它甚至似乎都没有通过序列化程序(调试时)。

知道如何反序列化,以便这个不属于模型的字段将成为新实例的一部分吗?

【问题讨论】:

    标签: django serialization


    【解决方案1】:

    如果您需要在反序列化后将owner 作为对象的属性,那么您需要根据documentation 中提到的要求更新createupdate 方法。

    在您的情况下,序列化程序将变为:

    class ItemSerializer(serializers.ModelSerializer):
        id = serializers.CharField(required=False, max_length=1000, allow_null=True)
        owner = serializers.SerializerMethodField()
        class Meta:
            model = Item
    
            fields = [
               'id',
               'owner'
            ]
    
        def get_owner(self, item):
             return item.package.owner if item.package else None
    
        def update(self, instance, validated_data):
            instance.email = validated_data.get('owner', 'default')
            return instance
    
        # same way for create
    

    此外,在反序列化时,您需要提供ser_item.data,而不是ser_item。还要保存序列化程序以触发更新/创建方法。 (感谢@user2880391指出这一点,我也错过了。)

    serializer = ItemSerializer(data=ser_item.validated_data)
    serializer.save()
    

    【讨论】:

    • 我的问题中的代码是错误的。我现在已经修好了。我确实使用 get_owner。如前所述 - 序列化确实有效,但反序列化无效。
    • 感谢您的回答。我可能遗漏了一些东西,但它看起来像在反序列化和创建新实例时 (serializer = ItemSerializer(data=ser_item.data)) - 它似乎根本没有进入 ItemSerializer 代码。即使我添加了创建和更新
    • 谢谢。我试过了,一开始并没有真正起作用。缺少的是 - 在我反序列化 (obj = Item(**serializer.validated_data)) 的地方,我应该一直使用 serializer.save(),这将触发 updatecreate 在我的情况下。如果您同意,请编辑答案,以便我标记它。
    猜你喜欢
    • 1970-01-01
    • 2016-07-21
    • 1970-01-01
    • 2016-10-14
    • 2014-12-24
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多