作用
1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
2. 完成数据校验功能
3. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
准备数据模型类booktest/model.py
class BookInfoSerializer(serializers.Serializer): """图书数据序列化器""" id = serializers.IntegerField(label='ID', read_only=True) btitle = serializers.CharField(label='名称', max_length=20) bpub_date = serializers.DateField(label='发布日期', required=False) bread = serializers.IntegerField(label='阅读量', required=False) bcomment = serializers.IntegerField(label='评论量', required=False) image = serializers.ImageField(label='图片', required=False)
我们为模型类提供一个序列化器.
class BookInfoSerializer(serializers.Serializer): """图书数据序列化器""" id = serializers.IntegerField(label='ID', read_only=True) #read_only 仅仅用于读取数据 btitle = serializers.CharField(label='名称', max_length=20) bpub_date = serializers.DateField(label='发布日期', required=False) bread = serializers.IntegerField(label='阅读量', required=False) bcomment = serializers.IntegerField(label='评论量', required=False) image = serializers.ImageField(label='图片', required=False)
二 查询库表
常见字段类型
字段构造方式 | |
---|---|
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=) |
作用 | |
---|---|
max_length | 最大长度 |
min_lenght | 最小长度 |
allow_blank | 是否允许为空 |
trim_whitespace | 是否截断空白字符 |
max_value | 最小值 |
min_value | 最大值 |
通用参数
参数名称 | 说明 |
---|---|
read_only | 表明该字段仅用于序列化输出,默认False |
write_only | 表明该字段仅用于反序列化输入,默认False |
required | 表明该字段在反序列化时必须输入,默认True |
default | 反序列化时使用的默认值 |
allow_null | 表明该字段是否允许传入None,默认False |
validators | 该字段使用的验证器 |
error_messages | 包含错误编号与错误信息的字典 |
label | 用于HTML展示API页面时,显示的字段名称 |
help_text | 用于HTML展示API页面时,显示的字段帮助提示信息 |
Serializer(instance=None, data=empty, **kwarg)
创建序列化器对象
- 参数1: instance=要序列化的模型数据
- 参数2: data=要反序列化器的字典数据
- 参数3: many= 是否要序列化多个模型数据,多条数据many=True,默认一条数据
- 参数4: context=序列化器使用的上下文,字典类型数据,可以通过context把视图中的数据,传递给序列化器内部使用
说明:
2)用于反序列化时,将要被反序列化的数据传入data参数
3)除了instance和data参数外,在构造Serializer对象时,还可通过context
serializer = AccountSerializer(account, context={
'request': request
}) #把数据传递给序列器
-
在客户端请求时,使用序列化器可以完成对数据的反序列化。
-
五 序列化
三步骤:
1 操作数据库
2 构造序列化器对象
3 响应数据
class BookInfoView(View): def get(self,request): # 操作数据库 books = BookInfo.objects.all() # 创建序列化器对象 serializer = BookInfo2Serializer(instance=books,many=True) # 通过 serializer.data 获取序列化完成以后的数据 print ( serializer.data ) # 返回数据 return JsonResponse(serializer.data,safe=False) #safe=Fase 表示跳过严格检验数据类型是否为dict
book_qs = BookInfo.objects.all() serializer = BookInfoSerializer(book_qs, many=True) serializer.data # [OrderedDict([('id', 2), ('btitle', '天龙八部'),
('bpub_date', '1986-07-24'), ('bread', 36), ('bcomment', 40),
('image', N]), OrderedDict([('id', 3), ('btitle', '笑傲江湖'),
('bpub_date', '1995-12-24'), ('bread', 20), ('bcomment', 80),
('image'ne)]), OrderedDict([('id', 4), ('btitle', '雪山飞狐'),
('bpub_date', '1987-11-11'), ('bread', 58), ('bcomment', 24),
('ima None)]), OrderedDict([('id', 5), ('btitle', '西游记'),
('bpub_date', '1988-01-01'), ('bread', 10), ('bcomment', 10),
('im', 'booktest/xiyouji.png')])]
六 反序列化
class BookInfo2Serializer(serializers.Serializer): # 自定义要反序列化的字段 id = serializers.IntegerField(label="主键ID",read_only=True) btitle = serializers.CharField(label="标题",required=True,min_length=1,max_length=20,validators=[check_btitle]) bpub_date=serializers.DateField(label="出版日期") bread=serializers.IntegerField(label="阅读量",min_value=0) bcomment=serializers.IntegerField(label="评论量",default=0) # required=False 反序列化时, 当前字段可以不填 is_delete=serializers.BooleanField(label="逻辑删除")
- 自定义验证方法
def validate_btitle(self,data): # 例如,图书名不能是红楼梦 if data=="红楼梦": # 抛出错误 raise serializers.ValidationError("红楼梦是禁书~") # 验证方法中,把数据值必须返回给字段,否则字段值为空 return data
# 自定义验证方法[验证多个或者所有字段,只能出现一次] def validate(self,data): # data 这个是所有字段的内容,字典类型 bread = data.get("bread") bcomment = data.get("bcomment") if bread>=bcomment: return data raise serializers.ValidationError("阅读量小于评论量,数据太假了") def create(self,validated_data): """保存数据,把字典转换成模型 validated_data 客户端提交过来,并经过验证的数据 """ instance = BookInfo.objects.create( btitle = validated_data.get("btitle"), bread = validated_data.get("bread"), bcomment = validated_data.get("bcomment"), bpub_date = validated_data.get("bpub_date"), is_delete = validated_data.get("is_delete"), )
注意:
1 验证单个字段,可以有多个方法 2 def validate_<字段名>(self,data): # data当前字段对应的值 3 验证多个或者所有字段,只能出现一次
(2)反序列化-数据保存view视图
前面的验证数据成功后,我们可以使用序列化器来完成数据反序列化的过程.这个过程可以把数据转成模型类对象.
from django.views import View from django.http import QueryDict from .serializers import BookInfo2Serializer class BookInfo2View(View): def post(self,request): """添加一本图书""" # 接受数据 data = request.POST # 反序列化 serializer = BookInfo2Serializer(data=data) # 1. 验证数据 # raise_exception=True 把验证的错误信息返回给客户端,同时阻止程序继续往下执行 serializer.is_valid(raise_exception=True) # is_valid调用验证方式: 字段选项validators->自定义验证方法[单字段]->自定义验证方法[多字段] # 验证成功后的数据 # print(serializer.validated_data) # 2. 转换数据成模型,同步到数据库中 result = serializer.save() # save会自动调用序列化器类里面声明的create/update方法,返回值是当前新增/更新的模型对象 # 响应数据 return JsonResponse(serializer.data) def put(self,request,pk): """更新一个图书""" # 根据id主键获取指定图书信息 book = BookInfo.objects.get(pk=pk) # 获取put数据 data = QueryDict(request.body) # 使用序列化器完成验证和反序列化过程 # partial=False接下里在反序列化中允许部分数据更新 serializer = BookInfo2Serializer(instance=book,data=data,partial=False
) serializer.is_valid(raise_exception=True) serializer.save() # 响应数据 return JsonResponse(serializer.data)
注意:
save之所以可以自动识别,什么时候执行create ,什么时候执行update
主要是看创建序列化器对象时,是否有传入instance参数,
有instance参数,则save会调用序列化器内部的update方法
没有instance参数,则save会调用序列化器内部的create方法
七 超级版序列化器(ModelSerializer)
serializers.py
from rest_framework import serializers from booktest.models import BookInfo class BookInfoModelSerializer(serializers.ModelSerializer): # 模型序列化器也可以自定义验证字段[当某些数据不存在于数据库时,但是需要前端提交过来的,可以进行自定义, # 例如,验证码,确认密码] class Meta: model=BookInfo fields = ["id","btitle"] # 可以给模型序列化器里面指定的字段设置限制选项 extra_kwargs = { "bread":{"min_length":0,"required":True}, } # 自定义验证方法[验证单个字段,可以有多个方法] # def validate_<字段名>(self,data): # data当前字段对应的值 def validate_btitle(self,data): # 例如,图书名不能是红楼梦 if data=="红楼梦": # 抛出错误 raise serializers.ValidationError("红楼梦是禁书~") # 验证方法中,把数据值必须返回给字段,否则字段值为空 return data # 自定义验证方法[验证多个或者所有字段,只能出现一次] def validate(self,data): # data 这个是所有字段的内容,字典类型 bread = data.get("bread") bcomment = data.get("bcomment") if bread>=bcomment: return data raise serializers.ValidationError("阅读量小于评论量,数据太假了")
views.py
############################################################################################################################### # 3 模型序列化器 # 1. 可以帮我们自动完成字段的声明[主要是从模型中的字段声明里面提取过来] # 2. 模型序列化器也可以帮我们声明了create和update方法的代码 ############################################################################################################################### from django.views import View from django.http import JsonResponse from .serializers import BookInfoModelSerializer class BookInfo3View(View): def post(self,request): """添加一本图书""" # 接受数据 data = request.POST # 反序列化 serializer = BookInfoModelSerializer(data=data) serializer.is_valid(raise_exception=True) result = serializer.save() # 响应数据 return JsonResponse(serializer.data) def put(self,request,pk): """更新一个图书""" book = BookInfo.objects.get(pk=pk) # 获取put提交的数据 data = QueryDict(request.body) serializer = BookInfoModelSerializer(instance=book,data=data,partial=True) serializer.is_valid(raise_exception=True) serializer.save() # 响应数据 return JsonResponse(serializer.data)