Registro de aprendizaje de serializadores en rest_framework

SerializerMethodField()

Para los campos de solo lectura, la clase principal del tipo de serializador llamará automáticamente a la función llamada get_{filed_name} para procesar el resultado devuelto.

Cómo utilizar:

 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 '未知'

inserte la descripción de la imagen aquí
A través de la clase SerializerMethodField, reprocesamos el parámetro de estado y agregamos una clase de visualización en chino. Tenga en cuenta que cn_status aquí es de solo lectura y no se puede modificar ni agregar.

análisis de código

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)

para agregar

inserte la descripción de la imagen aquí
Al consultar la documentación oficial, podemos ver que al usar el modelo como un objeto serializado, debe proporcionar el valor predeterminado de fuente, para que el marco pueda ubicar los campos específicos que deben mostrarse. Pero en SerializerMethodField, no está seguro qué campo del modelo usaremos para el procesamiento secundario, por lo que pasar * significa que se debe pasar todo el objeto del modelo.

Supongo que te gusta

Origin blog.csdn.net/qq_20728575/article/details/127509687
Recomendado
Clasificación