• django restframework Serializer field


    SerializerMethodField

    这是一个只读字段。它通过调用它所连接的序列化类的方法来获得它的值。它可用于将任何类型的数据添加到对象的序列化表示中。

    签名: SerializerMethodField(method_name=None)

    • method_name - 要调用序列化对象的方法的名称。如果不包含,则默认为 get_<field_name>.
      由 method_name 参数引用的序列化方法应该接受一个参数(除了 self),这是要序列化的对象。它应该返回你想要包含在对象的序列化表示中的任何内容。例如:

    场景介绍:一个用户往往对应多个角色,而角色字段并不在UserProfile表中,这就需要我们新增角色字段到user序列化中

    from .models import UserProfile
    from .models import UserRole
    
    class UserProfileSerializer(serializers.ModelSerializer):
        """
        show list serializer
        """
        role = serializers.SerializerMethodField()
    
        class Meta:
            model = UserProfile
            # fields = "__all__"
            fields = ["id", "username","role", "account", "really_name", "department", "tel_phone",
                      "create_time", "email", "last_time", "creator"]
    
        def get_role(self,obj):
            user_id = obj.id
            roles = [i.role.name for i in UserRole.objects.filter(user_id=user_id)]
            roles = ",".join(roles)
            return roles
    

    相反的场景:我们提交的表单数据存在于多表中(因为表中含有多对多字段),如何验证所有字段,并保存完整的数据到各表中。

    刚开始的思路在ModelSerializer中新增未定义字段,然后发现这并不可行。我也犯了SerializerMethodField的错误,但随后去读了serializer的源码,以及了解serializer的顺序,就知道SerializerMethodField仅用于list方法。
    问题的突破点到底在哪里呢,在drf serializer 官方文档中就有一个知识点,serializer.save(**kwargs),kwargs数据被绑定在serializer.validated_data对象上,当create或update的时候就会被添加进数据库,相当于validated_data.update(kwargs)
    实际源码不是这样子,但也就是这么个意思。

    重写Serializer create,update方法

    from rest_framework.utils import model_meta
    
        def create(self, validated_data):
            field= validated_data.pop('field_name')
            validated_data = validated_data
            instance = Model.objects.create(**validated_data)
            # ...外键表的操作
            return instance
    
        def update(self, instance, validated_data):
            field= validated_data.pop('field_name')
            info = model_meta.get_field_info(instance)
    
            for attr, value in validated_data.items():
                if attr in info.relations and info.relations[attr].to_many:
                    field = getattr(instance, attr)
                    field.set(value)
                else:
                    setattr(instance, attr, value)
            instance.save()
            # ...
            return instance
    
  • 相关阅读:
    UPC 5130 Concerts
    poj 1079 Calendar Game
    2018 ACM-ICPC 中国大学生程序设计竞赛线上赛
    CF932E
    浅谈Tarjan算法
    拉格朗日差值
    扩展欧几里得算法(exgcd)
    欧拉定理
    莫比乌斯反演
    除法分块
  • 原文地址:https://www.cnblogs.com/zenan/p/10735554.html
Copyright © 2020-2023  润新知