Serializers learning record in rest_framework

SerializerMethodField()

For read-only fields, the parent class of the serializer type will automatically call the function named get_{filed_name} to process the returned result.

How to use:

 class ExampleSerializer(self):
        extra_info = SerializerMethodField()

        def get_extra_info(self, obj):
            return ...  # Calculate some data to return.
# 实战代码来自 @大江狗,略微经过修改
class ArticleSerializers(serializers.ModelSerializer):
    author = serializers.HiddenField(default=serializers.CurrentUserDefault())
    cn_status = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = '__all__'
        read_only_fields = ('id', 'create_date')

    def get_cn_status(self, obj):
        status_dict = {
    
    'p': '已发表', 'd': '草稿'}
        if status_dict.get(obj.status):
            return status_dict[obj.status]
        return '未知'
# 也可以编写任意名字的函数,在 SerializerMethodField 实例化时以 method_name 传入字符串形式的函数名(不推荐)
class ArticleSerializers(serializers.ModelSerializer):
    author = serializers.HiddenField(default=serializers.CurrentUserDefault())
    # 实例化时传入自定义的函数名
    cn_status = serializers.SerializerMethodField(method_name='add_cn_status')

    class Meta:
        model = Article
        fields = '__all__'
        read_only_fields = ('id', 'create_date')
	# 自定义一个函数名
    def add_cn_status(self, obj):
        status_dict = {
    
    'p': '已发表', 'd': '草稿'}
        if status_dict.get(obj.status):
            return status_dict[obj.status]
        return '未知'

insert image description here
Through the SerializerMethodField class, we have reprocessed the status parameter and added a Chinese display class. Note that the cn_status here is read-only and cannot be modified or added.

code analysis

class SerializerMethodField(Field):
"""
该类是 Field 的子类
"""
    def __init__(self, method_name=None, **kwargs):
    # 初始化时接受 method_name 这一参数的值作为返回前二次处理的函数
        self.method_name = method_name
        # 设置要查找的模型字段为所有字段
        kwargs['source'] = '*'
        # 默认该字段为空字段 
        kwargs['read_only'] = True
        super().__init__(**kwargs)

    def bind(self, field_name, parent):
        # The method name defaults to `get_{field_name}`.
        # 如果初始化时没有传入对应 methhod_name,会自动将 get_{field_name} 这一形式的函数作为二次处理函数进行绑定
        if self.method_name is None:
            self.method_name = 'get_{field_name}'.format(field_name=field_name)

        super().bind(field_name, parent)

    def to_representation(self, value):
        method = getattr(self.parent, self.method_name)
        return method(value)

to add on

insert image description here
By consulting the official documentation, we can see that when using the model as a serialized object, you need to provide the default value of source, so that the framework can locate the specific fields that need to be displayed. But in SerializerMethodField, it is not sure which field in the model we will use for secondary processing, so passing in * means that the entire model object needs to be passed in.

Guess you like

Origin blog.csdn.net/qq_20728575/article/details/127509687
Recommended