【Django】REST_Framework框架——序列化器serializers源码解析

news2024/12/29 10:43:31

在这里插入图片描述

一、序列化器类——Serializer

1、序列化器的作用

序列化器的使用分两个阶段:

1、在客户端请求时,使用序列化器可以完成对数据的反序列化(将字典格式的数据转化为模型对象)。
2、在服务器响应时,使用序列化器可以完成对数据的序列化(将模型对象转化为字典格式的数据)。

1、反序列化操作,会将前端传递的数据request.data,先通过serializer.is_valid()校验,校验通过调用save()方法,调用ModelSerializer中的create()方法或者Update()方法并且返回instance模型对象(只限于ModelSerializer类)
2、序列化操作,将返回的模型对象instance与序列化器中的字段进行比对那些需要输出,serializer.data为将要输出的数据为字典格式,经过response以后变成json格式字符串

2、Serializer属性中选项参数

参数名称作用
max_length最大长度
min_length最小长度
allow_blank是否允许为空
trim_whitespace是否截断空白字符
max_value最大值
min_value最小值
参数名称说明
read_only该字段仅用于序列化输出,需要序列化输出时设置:read_only=True;默认为False
write_only该字段仅用于反序列输入,需要序列化输入时设置:write_only=True;默认为False
required该字段表示在反序列化输入时必须输入
default反序列化时使用的默认值
allow_null表明该字段是否允许传入None,默认False
validators对字段进行校验,定义在字段中
error_message当字段校验不通过时,报error_message的value值
label用于HTML展示API页面时,显示的字段名称
help_text用于HTML展示API页面时,显示的字段帮助提示信息

3、创建Serializer对象

Serializer的构造方法为:

Serializer(instance=None,data=None,**kwargs)
说明:
1、instance接收查询集对象或者模型对象
2、data接收前端传递的数据为json格式
3、除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据

4、反序列化

4.1、数据验证

使用序列化器进行反序列化输入时,需要进行验证,通过后,才能获取验证成功后的数据

serializer.is_valid()=True时:验证过通过;
serializer.is_valid()=False时:验证不通过;
serializer.validated_data:验证通过的数据;
验证失败,可以通过serializer.errors属性获取错误信息,返回字典,包含了字段和字段的错误;如果是非字段错误,可以通过修改REST framework配置中的NON_FIELD_ERRORS_KEY来控制错误字典中的键名。

4.2、validators:序列化字段中定义的选项参数

案例1:

class ProjectsSerializer(serializers.Serializer):
    create_time=serializers.DateTimeField(label='创建时间',help_text='创建时间',
                                          format='%Y年%m月%d日 %H时%M分%S秒',read_only=True)
    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间',
                                            format='%Y年%m月%d日 %H时%M分%S秒', read_only=True)
    name=serializers.CharField(label='项目名称',help_text='项目名词',
                               max_length=20,min_length=3,
                               error_messages={'min_length':'项目名称不能少于3位',
                                               'max_length':'项目名称不能大于20'},
    validators=[UniqueValidator(queryset=Projects.objects.all(),message='项目名称不能重复')])

案例2


def is_contains_keyword(value):
	is '项目' not in value:
		raise serializers.ValidationError("项目名称中必须包含'项目'关键字")

class ProjectsSerializer(serializers.Serializer):
    create_time=serializers.DateTimeField(label='创建时间',help_text='创建时间',
                                          format='%Y年%m月%d日 %H时%M分%S秒',read_only=True)
    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间',
                                            format='%Y年%m月%d日 %H时%M分%S秒', read_only=True)
    name=serializers.CharField(label='项目名称',help_text='项目名词',
                               max_length=20,min_length=3,
                               error_messages={'min_length':'项目名称不能少于3位',
                                               'max_length':'项目名称不能大于20'},
                               validators=[UniqueValidator(queryset=Projects.objects.all(),message='项目名称不能重复'),is_contains_keyword])

4.3、validate_字段名:对字段进行校验

单个字段进行校验:项目名称不能多于10个字

def is_contains_keyword(value):
	is '项目' not in value:
		raise serializers.ValidationError("项目名称中必须包含'项目'关键字")

class ProjectsSerializer(serializers.Serializer):
    create_time=serializers.DateTimeField(label='创建时间',help_text='创建时间',
                                          format='%Y年%m月%d日 %H时%M分%S秒',read_only=True)
    update_time = serializers.DateTimeField(label='更新时间', help_text='更新时间',
                                            format='%Y年%m月%d日 %H时%M分%S秒', read_only=True)
    name=serializers.CharField(label='项目名称',help_text='项目名词',
                               max_length=20,min_length=3,
                               error_messages={'min_length':'项目名称不能少于3位',
                                               'max_length':'项目名称不能大于20'},
                               validators=[UniqueValidator(queryset=Projects.objects.all(),message='项目名称不能重复'),is_contains_keyword])
	class Meta:
        model=Projects
        fields='__all__'
    
    def validate_name(self,attr:str):
    	if len(attr)>10:
    		raise serializers.ValidationError('项目名称不能多于10个字')
    	return attr

4.4、validate:多字段校验

class RegisterModelSerializer(serializers.ModelSerializer):
    password_confirm = serializers.CharField(label='确认密码', help_text='确认密码',
                                             error_messages={"min_length": "允许输入5-20个字符",
                                                             "max_length": "允许输入5-20个字符", },
                                             write_only=True)
    token = serializers.CharField(label='token', help_text='token', read_only=True)

    class Meta:
        model = User
        fields = ['id', 'username', 'password', 'password_confirm', 'token', 'email']

    # 校验密码与验证码密码
    def validate(self, attrs):
        password=attrs.get('password')
        password=attrs.get('password_confirm')
        if password!=password_confirm:
        	raise serializers.ValidationError('密码和确认密码不一致')
        return attrs

5、反序列化-保存数据

前面的验证数据成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象,可以通过定义create()和update()两个方法来实现。

def create(self,validated_data):
	......
	return instance

def update(self,validated_data):
	......
	return instance

二、模型类序列化器——ModelSerializer

如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。
在这里插入图片描述
在这里插入图片描述

父类中虽然提供了create()方法和update()方法,但是方法体是空的,如果子类需要使用,需要重写create()和update()方法

在这里插入图片描述

ModelSerializer与常规的Serializer相同,但提供了:

基于模型类自动生成一系列的字段与模型类中的字段名称一致
包含默认的create()和update()方法的实现

1、指定字段

使用fields来明确字段,__all__表名包含所有字段,

class NewsChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields='__all__'

也可以写明具体哪些字段,如

class NewsChannel1Serializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields=['id','url']

使用exclude可以明确排除掉哪些字段

class NewsChannel1Serializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        exclude=['url']

指明只读字段;可以通过read_only_fields指明只读字段,即仅用于序列化输出的字段

class NewsChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields='__all__'
        read_only_fields=['url','name']

我们可以使用 extra_kwargs参数为ModelSerializer添加或修改原有的选项参数

class NewsChannelSerializer(serializers.ModelSerializer):
    class Meta:
        model=NewsChannel
        fields='__all__'
        extra_kwargs={
			'name':{'max_length':10,'min_length':1,'required':True}
		}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/892.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络原理——No.4 传输层_TCP协议中的延迟应答, 捎带应答, 面向字节流与TCP的异常处理

JavaEE传送门JavaEE 网络原理——No.2 传输层_TCP的连接管理 网络原理——No.3 传输层_TCP的滑动窗口, 流量控制与拥塞控制 目录延迟应答捎带应答面向字节流粘包问题TCP 中的异常处理(连接异常)TCP 和 UDP 的应用场景延迟应答 一种提高传输效率的机制, 又是基于流量控制, 来引…

Appinventor——蓝牙app(蓝牙遥控器、串口助手、温湿度显示、切换界面蓝牙依旧保持连接)

App Inventor由谷歌实验室开发,移交麻省理工学院,是一款图形化编程环境,不需要复杂的变成语言,采用搭积木的方式编程,只需将组件拖入即可,简直就是不爱编程党的超级福音 本文搭建了一个蓝牙app&#xff0c…

【CSS】CSS基础认知【CSS基础知识详解】

🌸大家好,我是花无缺,一枚热爱生活的新时代青年,感谢你的阅读🥰~ 👨‍💻个人主页:花无缺 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 花无缺 原创 收录于专…

女朋友说她累了之后依然在线,于是20行代码写了个小工具康康发生了什么

近发现女朋友一到晚上总是很忙的样子, 每晚匆匆忙忙道过晚安就说自己累了去睡觉。 是我哪里做的不对吗… 睡就睡了,可是,QQ头像却会偶尔亮起来, 我非常担心,是不是账号被盗了呢? 然后,就想帮…

Django全家桶

Django框架从入门到高级 (一)Django入门 Web应用 详细地址见:https://blog.csdn.net/DiligentGG/article/details/126606099?spm1001.2014.3001.5501 Web框架本质 web框架本质上可以看成是一个功能强大的socket服务端,用户的…

Android专有GitHook完结篇,发布到npm

系列文章目录 Android打造专有hook,让不规范的代码扼杀在萌芽之中 Android打造专有hook第二篇,走进规范第一步 Android打造专有Hook第三篇,实战全量代码规范检查 Android打造专有Hook第四篇,实战增量代码规范检查 Hello啊各位…

【NLP】词向量

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

阿里巴巴面试题- - -多线程并发篇(三十)

前言:七月末八月初的时候,秋招正式打响,公司会放出大量的全职和实习岗位。为了帮助秋招的小伙伴们,学长这里整理了一系列的秋招面试题给大家,所以小伙伴们不用太过焦虑,相信你们一定能超常发挥,收到心仪公司的Offer~~ 内容涵盖:Java、MyBatis、ZooKeeper、Dubbo、Elast…

窥一斑而知全豹,从五大厂商看MCU国产化的机遇和挑战

👆👆👆 #电巢直播10月26日(周三)扫码参与 前言 近年来,MCU在各领域的应用大幅度增加。2021年全球MCU的总出货量仍旧增长12%,使去年全球MCU的交付量达到了309亿片的历史新高。根据IC Insights…

工业控制系统安全评估流程系统评定与分类

综述 随着计算机和网络技术的发展,特别是信息化与工业化## 综述 随着计算机和网络技术的发展,特别是信息化与工业化深度融合以及物联网的快速发展,工业控制 系统产品越来越多地采用通用协议、通用硬件和通用软件,网络威胁正在由传…

Linux文件属性与权限

目录 前言 文件权限类 文件属性 rwx 作用文件和目录的不同解释 chmod 改变权限 1)基本语法 2)经验技巧 3)案例实操 chown 改变所有者 1)基本语法 2)选项说明 3)实操案例 chgrp 改变所属组 …

康为世纪科创板上市破发:跌幅超10% 公司市值41亿

雷递网 雷建平 10月25日江苏康为世纪生物科技股份有限公司(简称:“康为世纪”,股票代码为“688426”)今日在科创板上市。康为世纪此次发行价为48.98元,发行2329万股,募资总额为11.4亿元。康为世纪开盘价为4…

【单片机毕业设计】【mcuclub-jj-048】基于单片机的水表的设计

最近设计了一个项目基于单片机的水表系统,与大家分享一下: 一、基本介绍 项目名:水表 项目编号:mcuclub-jj-048 单片机类型:STC89C52 具体功能: 1、通过继电器控制水泵,将水抽出经过流速传感器…

Redis实战篇一 (短信登录)

Redis企业实战(黑马点评)项目整体架构项目部署后端部署前端部署短信登陆基于Session实现登录集群的Session共享问题基于Redis实现共享session登录解决状态登录刷新的问题——登录拦截器的优化本期学习路线短信登陆: Redis的共享session应用 商户查询缓存…

jar包突然过大解决方法,解决ffmpeg剪辑视频导致jar过大

jar包突然过大解决方法 缘由: ​ 项目中要需要用到视频文件,为了方便用户使用,那么页面中就需要增加视频剪辑的相关功能,让用户上传视频后能够自定义的进行剪辑,对自己的视频做出相应的更改 结果: ​ 打jar…

Vue复刻华为官网 (二)

文章目录1 推荐信息1.1 思路1.2 代码1.3 知识补充1.4 效果图2 宣传海报2.1 思路2.2 代码2.3 效果图3 新闻与活动3.1 思路3.2 代码3.3 效果图1 推荐信息 1.1 思路 看了这个gif后,可以清楚的看到产生了三个动画效果:图片"拉近","…

js 实现页面隐藏、关闭、刷新给出对应的提示

我们在做项目的时候经常会遇到一些需求,比如在某些页面当点击浏览器刷新 或者关闭的时候会有对应的提示,是否离开或者重新加载此网站。比如csdn写文章的时候就有这个弹窗,这功能就是用onbeforeunload实现的。 注意:如果你加载下面…

学会用Linux用户管理命令

目录 useradd 添加新用户 1)基本语法 2)案例实操 passwd 设置用户密码 1)基本语法 id 查看用户是否存在 1)基本语法 2)案例实操 cat /etc/passwd 查看创建了哪些用户 1)案例实操 su 切换用户 1…

Linux基本工具(上)

目录 粘滞位:t yum yum install yum list ​编辑 yum list | grep 软件名 yum search 软件名 软件卸载:yum remove rz sz表示下载: Linux开发工具: vim编辑器: vim的几种模式: 粘滞位&#xff1a…

蛇形矩阵求解

题目: 题解思考: 这个题目我有两种解题方法: 1)利用数组,数组的下标。 2)利用等差数列的规律(这个可能比较难理解),行和列的递增规律。 注意输出格式的处理和多组输入…