魔改SerializerMethodField-可读可写

魔改SerializerMethodField-可读可写

April 180 2023-01-31

Django SerializerMethodField简单介绍

Django SerializerMethodField 官方第一句话就是这是一个只读的字段,在实际序列化的过程中也是非常好用的。
WX20230131-180457@2x
但是有时候就是那么蛋疼,我即想在序列化的时候做一些骚操作,又想可以更改。(请忽略这个骚操作是否符合rest farmework的精神内在)

读源码

WX20230131-181031@2x
再源码中,代码有一个 kwargs['read_only'] = True 基本上可以看到只读的属性出自这里。同时对比其他类型可写的Field,发现少了一个to_internal_value 函数 image-1675160236418

to_internal_value

to_internal_value 是做乜野的?简单来说to_internal_value 就是用于验证序列化程序的更新请求,基本上需要入库之前都会走一遍to_internal_valueto_internal_value to_representation基本上是一对难兄难弟。

  1. to_representation() 允许我们改变序列化的输出。
  2. to_internal_value() 允许改变我们反序列化的输出。

get_attribute

除此之外,还需要有get_attribute这个方法(当然是在一遍遍报错中找到的啦),按照ModelField中的get_attribute超一个就好啦!
image-1675160777232
image-1675160665305

最终魔改

class SerializerWriteMethodField(SerializerMethodField):
    def __init__(self, method_name=None, read_only=True, trim_whitespace=False, **kwargs):
        self.method_name = method_name
        super(SerializerMethodField, self).__init__(**kwargs)
        self.read_only = read_only
        self.trim_whitespace = trim_whitespace

    def to_internal_value(self, data):
        value = six.text_type(data)
        return value.strip() if self.trim_whitespace else value

    def get_attribute(self, obj):
        return obj

如何使用

https://blog.csdn.net/weixin_44649870/article/details/99877171
这个链接里有提到只读的问题,依次链接的代码为例


class TestSerializer(serializers.ModelSerializer):
    status = SerializerWriteMethodField(read_only=False)
    
    def get_status(selef, obj):
        return "是" if obj.status else "否" 
    
    class Meta:
        model = TestModel
        fields = ("id", "status")    

image-1675161173642

okk了!