序列化之Serializer类与ModelSerializer类的使用
序列化之Serializer类的使用(5星)
作用:
- 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
- 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
- 反序列化,完成数据校验功能
基本使用
模型类
class Books(models.Model):
title = models.CharField(max_length=32)
price = models.IntegerField()
publish = models.CharField(max_length=32)
序列化类
from rest_framework import serializers
from .models import Books
# 想要序列化和反序列化的book表
class BookSerializer(serializers.Serializer):
title = serializers.CharField() # 这里的max_length是限制反序列化时的条件
price = serializers.IntegerField()
publish = serializers.CharField() # 这里的max_length也是限制反序列化时的条件
# 如果要更新 一定要重写update方法
def update(self, instance, validated_data):
# 修改数据
instance.title = validated_data.get('title')
instance.price = validated_data.get('price')
instance.publish = validated_data.get('publish')
# 保存
instance.save()
# 返回
return instance
# 如果要新增 一定要重写create方法
def create(self, validated_data):
# 保存
book_obj = Books.objects.create(**validated_data)
# 返回
return book_obj
视图类
from .models import Books
from .serializer import BookSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
class BookAPIView(APIView):
# 查询所有的接口
def get(self, request, *args, **kwargs):
book_list = Books.objects.all()
# 把queryset对象序列化成字典
# 第一个参数是传要序列化的对象 如果有多条数据对象 那么要加many=True
ser = BookSerializer(instance=book_list, many=True)
print(ser.data)
return Response(ser.data)
# 新增的接口
def post(self, request, *args, **kwargs):
ser = BookSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response(ser.data)
# 查询单个接口
class BookDetailAPIView(APIView):
# 查询单个
def get(self, request, pk):
# 查出主键值为pk的书
book_obj = Books.objects.filter(pk=pk).first()
ser = BookSerializer(instance=book_obj)
return Response(ser.data)
def delete(self, request, pk):
# 删除主键为pk的书
res = Books.objects.filter(pk=pk).delete() # res代表影响的行数
if res:
return Response()
def put(self, request, pk):
# 先查出主键为pk的书
book_obj = Books.objects.filter(pk=pk)
# 反序列化 修改数据
ser = BookSerializer(instance=book_obj, data=request.data)
# 校验数据
if ser.is_valid():
ser.save()
return Response(ser.data)
路由
urlpatterns = [
# drf继承APIView的路由
path('books/', views.BookAPIView.as_view()),
path('books/<int:pk>', views.BookDetailAPIView.as_view()),
]
序列化类字段和字段参数(2星)
字段类型
# 字段(必须记住)
CharField
IntegerField
FloatField
DecimalField
DateTimeField
DateField
# 知道--》models中没有的---》反序列化的时候,前端传入的
{name:lqz,age:19,hobby:[篮球,足球],wife:{name:lyf,age:38}}
ListField
DictField
| 字段 | 字段构造方式 |
|---|---|
| BooleanField | BooleanField() |
| NullBooleanField | NullBooleanField() |
| CharField | CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True) |
| EmailField | EmailField(max_length=None, min_length=None, allow_blank=False) |
| RegexField | RegexField(regex, max_length=None, min_length=None, allow_blank=False) |
| SlugField | SlugField(maxlength=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9-]+ |
| URLField | URLField(max_length=200, min_length=None, allow_blank=False) |
| UUIDField |
UUIDField(format=’hex_verbose’) format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
|
| IPAddressField | IPAddressField(protocol=’both’, unpack_ipv4=False, **options) |
| IntegerField | IntegerField(max_value=None, min_value=None) |
| FloatField | FloatField(max_value=None, min_value=None) |
| DecimalField | DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置 |
| DateTimeField | DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None) |
| DateField | DateField(format=api_settings.DATE_FORMAT, input_formats=None) |
| TimeField | TimeField(format=api_settings.TIME_FORMAT, input_formats=None) |
| DurationField | DurationField() |
| ChoiceField | ChoiceField(choices) choices与Django的用法相同 |
| MultipleChoiceField | MultipleChoiceField(choices) |
| FileField | FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ImageField | ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL) |
| ListField | ListField(child=, min_length=None, max_length=None) |
| DictField | DictField(child=) |
字段参数
# 重点:
read_only:表明该字段仅用于序列化输出,默认False
-如果read_only=True,这个字段只用来做序列化---》把对象---》json给前端
write_only:表明该字段仅用于反序列化输入,默认False
-如果read_only=write_only,这个字段只用来做反序列化---》前端json---》存到数据库
选项参数:
| 参数名称 | 作用 |
|---|---|
| max_length | 最大长度(CharField) |
| min_lenght | 最小长度(CharField) |
| allow_blank | 是否允许为空(CharField) |
| trim_whitespace | 是否截断空白字符(CharField) |
| max_value | 最小值 (IntegerField) |
| min_value | 最大值(IntegerField) |
通用参数:
| 参数名称 | 说明 |
|---|---|
| read_only | 表明该字段仅用于序列化输出,默认False |
| write_only | 表明该字段仅用于反序列化输入,默认False |
| required | 表明该字段在反序列化时必须输入,默认True |
| default | 反序列化时使用的默认值 |
| allow_null | 表明该字段是否允许传入None,默认False |
| validators | 该字段使用的验证器(不太用) |
| error_messages | 包含错误编号与错误信息的字典 |
| label | 用于HTML展示API页面时,显示的字段名称 |
| help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |

Serializer高级使用(5星)
source和serializers.SerializerMethodField()的用法
source参数
让序列化的字段映射到表模型的某个字段或方法上,可以使用 . 字段深度取值
1.直接指名道姓的指定对应的字段
class BookSerializer(serializers.Serializer):
book_title = serializers.CharField(source='title') # 这里指定和book类里的title做对应 等号前就可以随便写了
price = serializers.IntegerField()
publish = serializers.CharField()
# 也可以.深度取值
class BookSerializer(serializers.Serializer):
book = serializers.CharField()
publish = serializers.CharField(sourse='publish.name') # 该字段就可以跨表拿到publish的名字
2.指定某方法
在model.py内
class Books(models.Model):
title = models.CharField(max_length=32)
price = models.IntegerField()
publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
def publish_detail(self): # 定义一个展示出版社详细信息的方法
return {'name': self.publish.name, 'addr': self.publish.addr}
class Publish(models.Model):
name = models.CharField(max_length=32)
addr = models.CharField(max_length=32)
在自定义序列化py里
class BookSerializer(serializers.Serializer):
title = serializers.CharField()
price = serializers.IntegerField()
publish = serializers.CharField(source='publish_detail') # 这个和下面的结果一样 只是两种写法
publish_detail = serializers.CharField() # 两个结果都是显示model.py里定义的那个方法的返回值

总结
source可以对应表模型的字段和方法(返回结果是什么,字段就是什么), 对应字段就是指名道姓的一一对应,对应方法一般用来做一对多,多对多的字段返回,如上面跨表得到publish的详细信息
SerializerMethodField
class BookSerializer(serializers.Serializer):
title = serializers.CharField()
price = serializers.IntegerField()
publish = serializers.SerializerMethodField() # 必须对应一个方法 def get_字段名,不然报错
def get_publish(self, obj): # obj是该类要x的对象
print(obj)
return {'name': obj.publish.name, 'addr': obj.publish.addr}
# 然后结果是publish字段就会返回上面你自定义的结果

总结
和source结果一样,只是一个在表模型里面写方法(source),一个是在序列化类里面写方法(SerializerMethodField)
字段本身校验
name=serializers.CharField(max_length=8,min_length=3)
# 这句话就是最大为8 最小为3 不符合条件就不会被入库
局部钩子函数
在该序列化类里
# 局部钩子函数
def validate_name(self, name):
if name.startswith('sb'):
from rest_framework.exceptions import ValidationError
# 主动抛异常
raise ValidationError('不能以sb开头')
else:
return name

全局钩子函数
# 全局钩子函数
def validate(self, attrs): # attrs是一个字典,里面有所有字段的信息{'字段':'数据'}
if attrs.get('name').endswith('sb') or '日本' in attrs.get('addr'):
from rest_framework.exceptions import ValidationError
raise ValidationError('名称和地址不能出现sb和日本')
return attrs # 别忘了把数据返回

模型类序列化器ModelSerializer使用(5星)
基本使用
class BookModelSerializer(serializers.ModelSerializer): # 继承ModelSerializer
class Meta:
model = Books # 和指定的表关联
fields = ['id', 'name', 'publish_detail'] # 指定字段或方法
fields = '__all__' # 指定所有字段(不包括方法)
exclude = ['id'] # 从所有的字段中排除(不包括方法)
'''
上面3个只能写一个,看需求使用
'''
depth = 1 # 查询深度 效果见下图
''' class Meta里的数据就这么多 其他的类似重写字段等等的方法需要和class Meta保持同级,不能在class Meta内部'''

重写字段
class BookModelSerializer(serializers.ModelSerializer):
# 指定和哪个表作关联
class Meta:
model = Books
fields = '__all__' # 指定所有字段
# 重写字段(修改数据)
title = serializers.SerializerMethodField()
def get_title(self, obj): # 和SerializerMethodField用法一样 也必须指定一个方法: get_字段名
return '经典名著' + obj.title

扩写字段(表模型中没有的字段)
在models.py内定义一个方法:
def publish_detail_str(self):
return {'name': self.publish.name, 'addr': self.publish.addr}
# 多写字段
publish_detail = serializers.CharField(source='publish_detail_str')
# 反序列化新增接收的字段
phone = serializers.CharField(max_length=20, write_only=True)
addr = serializers.CharField(max_length=20, write_only=True)

反序列化新增接收的字段及应用
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ['id', 'name', 'age', 'phone', 'addr', 'author_detail']
extra_kwargs = {
'author_detail': {'read_only': True},
}
##########################新增两个字段用来反序列化接收数据##############################
phone = serializers.CharField(max_length=20, write_only=True)
addr = serializers.CharField(max_length=20, write_only=True)
########因为和作者详情表是一对一,直接和作者详情表的字段写的一样,这样还能有字段校验########
###################重写create方法,在这里面把接收到的数据保存到两张表里##################
def create(self, validated_data):
name = validated_data.get('name')
age = validated_data.get('age')
phone = validated_data.get('phone')
addr = validated_data.get('addr')
###################先保存作者详情表的,再保存作者表,不然会保存不进去###################
author_detail_obj = AuthorDetail.objects.create(phone=phone, addr=addr)
author_obj = Author.objects.create(name=name, age=age, author_detail=author_detail_obj)
return author_obj
反序列化字段校验
字段本身的校验是映射了表模型中的字段规则
# 在models.py中
class Publish(models.Model):
name = models.CharField(max_length=32, unique=True)
addr = models.CharField(max_length=32)
# 如果在序列化类里什么限制都不写 那么会按照字段本身的校验规则


重新定义
class PublishModelSerializer(serializers.ModelSerializer):
# 指定和哪个表作关联
class Meta:
model = Publish
fields = '__all__'
name = serializers.CharField(max_length=1) # 重新设置字段的校验规则

局部钩子函数
from rest_framework.exceptions import ValidationError
# 局部钩子
def validate_name(self, name):
if name.startswith('sb'):
raise ValidationError('不能以sb开头')
return name

全局钩子函数
from rest_framework.exceptions import ValidationError
# 全局钩子函数
def validate(self, attrs):
if attrs.get('name').endswith('sb') or '日本' in attrs.get('addr'):
raise ValidationError('名称和地址不能出现sb和日本')
return attrs

额外添加参数(extra_kwargs)
class PublishModelSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
fields = '__all__'
# 把字段需要的参数全部写进字典
extra_kwargs = {'name': {'write_only': True, 'max_length': 8}, 'addr':{...}}

wirte_only和read_only
基本用法
write_only
class PublishModelSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
fields = '__all__' # 指定所有字段
name = serializers.CharField(write_only=True) # 只写(不能读)

read_only
class PublishModelSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
fields = '__all__' # 指定所有字段
name = serializers.CharField(read_only=True) # 只读(不能写)

应用场景
class PublishModelSerializer(serializers.ModelSerializer):
# 指定和哪个表作关联
class Meta:
model = Publish
fields = '__all__' # 指定所有字段
name_detail = serializers.SerializerMethodField(read_only=True) # 设置只读
def get_name_detail(self, obj):
return 'xxx' + obj.name
name = serializers.CharField(write_only=True) # 设置只写


序列化之Serializer类与ModelSerializer类的使用的更多相关文章
- drf框架serializers中ModelSerializer类简化序列化和反序列化操作
0905自我总结 drf框架serializers中ModelSerializer类 基于seriallizer类进行简化 https://www.cnblogs.com/pythonywy/p/11 ...
- 4)drf序列化组件 Serializer(偏底层)、ModelSerializer(重点)、ListModelSerializer(辅助群改)
知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 一.Serializer 偏底层 一般不用 理解原理 1.序列化准备 ...
- [序列化] SerializeHelper--序列化操作帮助类 (转载)
点击下载 SerializeHelper.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.XML序列化2.Json序列化3.SoapFormatter序列化4.BinaryFormatte ...
- 【Springboot】FastJson与Jackson全局序列化方式的配置和相关工具类
springboot 版本: <parent> <groupId>org.springframework.boot</groupId> <artifactId ...
- java中POJO类和DTO类都要实现序列化
java中POJO类和DTO类都要实现序列化 java中POJO类和DTO类都要实现序列化 java中POJO类和DTO类都要实现序列化 序列化:序列化是将对象转换为容易传输的格式的过程.例如,可以序 ...
- drf03 drf视图中提供的请求类和响应类
drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作.所以在django原有的django.views.View类基础上,drf封装了多个子类出来提供给我们使用. Django REST ...
- python测试开发django-rest-framework-64.序列化(serializers.Serializer)
前言 REST framework中的serializers与Django的Form和ModelForm类非常像.我们提供了一个Serializer类,它为你提供了强大的通用方法来控制响应的输出, 以 ...
- drf框架 - 序列化组件 | Serializer
序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer(辅助群改) 序列化与反序列化 序列化: 将对象序列化成字符串用户传输 ...
- 第三章、drf框架 - 序列化组件 | Serializer
目录 第三章.drf框架 - 序列化组件 | Serializer 序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer( ...
随机推荐
- SAS 数值存储方式和精度问题
本文链接:https://www.cnblogs.com/snoopy1866/p/16021137.html 1 数值存储方式 SAS使用8个字节存储数值,使用浮点计数法表示数值. 浮点计数法由4个 ...
- 敏捷开发之Scrum方法运用
目前软件开发除了强调产品质量,同时对产品能够快速发布并且迅速适应市场变化的要求也日益强烈.为适应这种开发环境和市场需求,传统的软件开发模式已被敏捷开发模式所替代.本文介绍敏捷软件开发中的Scrum方法 ...
- 三大主流软件负载均衡器对比(LVS & Nginx & Haproxy)
LVS:1.抗负载能力强.抗负载能力强.性能高,能达到F5硬件的60%:对内存和cpu资源消耗比较低2.工作在网络4层,通过vrrp协议转发(仅作分发之用),具体的流量由linux内核处理,因此没有流 ...
- spinlock 设计的初衷,当只有单核时是否还需要锁
自旋锁,的设计初衷是什么,是为了解决什么问题.如果只有一个cpu,并且是单核,那是否还需要用到自旋锁.
- Apache+tomcat实现应用服务器集群
Ngnix/Apache比较 Nginx:Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行.其特点是占有内存少,并发能力 ...
- Redis Cluster 集群搭建与扩容、缩容
说明:仍然是伪集群,所有的Redis节点,都在一个服务器上,采用不同配置文件,不同端口的形式实现 前提:已经安装好了Redis,本文的redis的版本是redis-6.2.3 Redis的下载.安装参 ...
- KestrelServer详解[1]:注册监听终结点(Endpoint)
具有跨平台能力的KestrelServer是最重要的服务器类型.针对KestrelServer的设置均体现在KestrelServerOptions配置选项上,注册的终结点是它承载的最重要的配置选项. ...
- SQL语句分为哪几种?
SQL语句主要可以划分为以下几类: DDL(Data Definition Language):数据定义语言,定义对数据库对象(库.表.列.索引)的操作. 包括:CREATE.DROP.ALTER.R ...
- RabbitMQ-learning
第一种模式=直连 P:生产者,也就是要发送消息的程序 C:消费者:消息的接受者,会一直等待消息到来. queue:消息队列,图中红色部分.类似一个邮箱,可以缓存消息:生产者向其中投递消息,消费者从其中 ...
- elasticsearch 了解多少,说说你们公司 es 的集群架构,索 引数据大小,分片有多少,以及一些调优手段 。
面试官:想了解应聘者之前公司接触的 ES 使用场景.规模,有没有做过比较大 规模的索引设计.规划.调优. 解答: 如实结合自己的实践场景回答即可. 比如:ES 集群架构 13 个节点,索引根据通道不同 ...