Django rest framework 序列化类

serializers是什么?官网是这样的”Serializers allow complex data such as querysets and model instances to be converted to native Python datatypes that can then be easily rendered into JSON, XML or other content types. “翻译出来就是,将复杂的数据结构变成json或者xml这个格式的。
  
在最近的学习中,个人看法,serializers有以下几个作用:

  • 将queryset与model实例等进行序列化,转化成json格式,返回给用户(api接口)。
  • 将post与patch/put的上来的数据进行验证。
  • 对post与patch/put数据进行处理。

联合validate

对 POST 过来的所有数据进行验证,那么我们就可以重载validate( )方法。

start = serializers.DateTimeField()
finish = serializers.DateTimeField()

def validate(self, attrs):
# 传进来什么参数,就返回什么参数,一般情况下用attrs
    if data['start'] > data['finish']:
        raise serializers.ValidationError("finish must occur after start")
    return attrs

这个方法非常的有用,我们还可以再这里对一些read_only的字段进行操作,我们在read_only提及到一个例子,订单号的生成,我们可以在这步生成一个订单号,然后添加到attrs这个字典中

order_sn = serializers.CharField(readonly=True)
def validate(self, attrs):
    # 调用一个方法生成order_sn
    attrs['order_sn'] = generate_order_sn()
    return attrs

这个方法运用在modelserializer中,可以剔除掉write_only的字段,这个字段只验证,但不存在与指定的model当中,即不能save( ),可以在这delete掉!

总结:

  1. 可以利用Serializer 类中定义的字段的参数 required = True/ False 来控制在 POST 请求时用不用传入该字段。如果在 Model 类中定义 了一个没有默认值的且不允许为空的字段同时在Serializer 类并没有显示的定义该字段或定义了但是没有设置 required=False,则会提示 {“xxx”:[“该字段是必填项。”]},流程都没进入 validate函数。
    如果通过 required=False 避免出现“ {“xxx”:[“该字段是必填项。”]}”,则虽然会进入到 validate 函数,但是在 xxx.objects.create()也还是会报(“Column ‘xxx’ cannot be null”)错的。
    可以通过给 attrs[‘xxx’]=‘yyy’ 赋值 比如上文提到的订单号来解决

  2. 如果在 POST 请求中携带了不在序列化类中定义的 key, 则该 key 和其 value 会在进入 validate 函数前被框架给去掉即打印参数 attrs 是看不到该 key 的
    参数 attrs 的内容就是
    a. POST 请求携带的数据(去掉没在Model类&序列化类中定义的 key 和 去掉 read_only = True 的 key)
    b. Serializer 类中定义含有默认值的字段
    c. Model 定义的唯一约束中含有默认值的字段

    对于b 参考: DataBaseInfoSerializer 中的 create_user =serializers.PrimaryKeyRelatedField(
    default=serializers.CurrentUserDefault(),queryset=User.objects.all())
    对于 c: 参考 API api/v1/db_operator/database_info 中的 src_or_dest 字段,因为在 Model 中定义了唯一约束 unique_together = (‘db_host’, ‘db_port’, ‘db_name’, ‘src_or_dest’))

  3. 如果在Serializer 类中定义定义了 Model 中没有的字段(可以定义为 write_only 比如验证码),这是可以的不过需要在 validate 函数中使用完该字段后再 pop 出去即可,否则在执行 serializer.save() 是会报
    TypeError: Got a TypeError when calling DataBaseInfo.objects.create(). This may be because you have a writable field on the serializer class that is not a valid argument to DataBaseInfo.objects.create(). You may need to make the field read-only, or override the DataBaseInfoSerializer.create() method to handle this correctly.
    设置为 read-only后,根据第一条可知 attrs 就不会携带该字段了也就不用 pop 了。

    对于 read_only 表示的意思是:只需要将它序列化传递给用户,假设需要返回用户加入这个网站多久了,不可能维持这样加入的天数这样一个数据,一般会记录用户加入的时间点,然后当用户获取这个数据,我们再计算返回给它。 write_only 和 read_only 都是对前端用户而言的。
    根据经验:一般在 Serializer 类 中指定为 write_only 和 read_only 的字段都是 Model 中没定义的字段。比如你在 Serializer 类 中定义了一个 write_only 字段其同时也在 Model 中定义了,经测试在处理 GET 请求时当然 Meta 类中的 fields 中是包含了该字段的,前端也看不到(即第4条的结论)。猜测是为了统一处理 write_only 字段在和不在 Model 中定义的两种情况,比如某个字段没有在指定model中定义,它是 write_only,需要用户传进来,我们是不能对它进行save( )的,所以就需要从 attrs 中 pop 出去,那么自然在处理 GET 请求时就不能返回。

  4. 如果在Serializer 类中没有显示的定义 Model 中有的字段:
    在处理 POST 请求时,如果 Model 中定义的字段没有默认值同时 POST 请求也没有携带该字段,则会提示 {“xxx”:[“该字段是必填项。”]}。 (Model 中定义的字段定义的字段都需要传入除非有默认值或者Serializer中定义该字段有默认值 or required=False or allow_null=True or read_only=True)
    在处理 GET 请求时,会根据 Meta 类中的 fields 来返回数据(忽略 write_only = True 的字段),Serializer类中字段的 to_representation 控制着输出格式

参考: https://blog.csdn.net/l_vip/article/details/79156113

发布了44 篇原创文章 · 获赞 0 · 访问量 3940

猜你喜欢

转载自blog.csdn.net/cpxsxn/article/details/102937639
今日推荐