序列化器:
作用:
序列化:
数据之间的相互转换,数据结构类型转换为其他格式(字典,JSON,XML等),将Django的模型类对象转换为JSON字符串
反序列化:
反之,将其他格式转换为程序整的数据,例如将JSON字符串转换为Django中的模型类对象
1.1定义:
能够参考模型序列化器:
"""
定义序列化器
1.定义类,继承自Serializer
2.和模型类,字段,类型,选项一样
read_only=True 只读
label 字段说明
"""
代码(book/serializers.py):
#1.定义序列化器
class BookInfoSerializer(serializers.Serializer):
id = serializers.IntegerField(label='id',read_only=True)
btitle = serializers.CharField(max_length=20, label='名称')
bpub_date = serializers.DateField(label='发布日期')
bread = serializers.IntegerField(default=0, label='阅读量')
bcomment = serializers.IntegerField(default=0, label='评论数')
is_delete = serializers.BooleanField(default=False, label='逻辑删除')
代码(book/model.py):
from django.db import models
#定义图书模型类
class BookInfo(models):
btitle = models.CharField(max_length=20,verbose_name='名称')
bpub_date = models.DateField(verbose_name='发布日期')
bread = models.IntegerField(default=0,verbose_name='阅读量')
bcomment = models.IntegerField(default=0,verbose_name='评论数')
is_delete = models.BooleanField(default=False,verbose_name='逻辑删除')
class Meta:
db_table = 'tb_books' # 知名数据库名称
verbose_name = '图书' #admin站点中显示的名称
verbose_name_plural = verbose_name #显示的复数名称
def __str__(self):
'''定义每个数据对象的显示信息'''
return self.btitle
1.2序列化器,序列化单个对象
操作流程(book/view.py)
'''===========1.序列化器,序列化单个书籍对象==========='''
from .serializers import BookInfoSerializer
from .models import BookInfo
#1.获取书籍对象
book = BookInfo.objects.get(id=1)
#2.创建序列化器,instance,表示要序列化的对象
serializer = BookInfoSerializer(instance=book)
#3.转换数据
print(serializer.data)
'''
结果:
{'id': 1, 'btitle': '西游记', 'bpub_date': '2021-04-21', 'bread': 30, 'bcomment': 39, 'is_delete': False}
'''
注意点:
BookInfoSerializer(instance=book)
instance=book:表示将book序列化
serializer.data:获取序列化的结果
序列化器,序列化列表
操作流程(book/view.py)
#1.获取书籍对象
books = BookInfo.objects.all()
#2.创建序列化器,instance,表示要序列化的对象,many=True 表示序列化多个对象
serializer = BookInfoSerializer(instance=books,many=True)
#3.转换数据
print(serializer.data)
'''
结果:
[OrderedDict([('id', 1), ('btitle', '西游记'), ('bpub_date', '2021-04-21'), ('bread', 30), ('bcomment', 39), ('is_delete', False)]),
OrderedDict([('id', 2), ('btitle', '水浒传'), ('bpub_date', '2021-04-08'), ('bread', 40), ('bcomment', 30), ('is_delete', False)])]
'''
注意点:
BookInfoSerializer(instance=book,many=True)
many=True:表示序列化多个对象
英雄序列化器
操作流程(book/serializers.py):
定义英雄序列化器:
class HeroInfoSerializer(serializers.Serializer):
"""英雄数据序列化器"""
GENDER_CHOICES = (
(0, 'male'),
(1, 'female')
)
id = serializers.IntegerField(label='ID', read_only=True)
hname = serializers.CharField(label='名字', max_length=20)
hgender = serializers.ChoiceField(choices=GENDER_CHOICES, label='性别', required=False)
hcomment = serializers.CharField(label='描述信息', max_length=200, required=False, allow_null=True)
定义关联字段:
class HeroInfoSerializer(serializers.Serializer):
......
#1,添加外键,主键表示 必须提供`queryset` 选项, 或者设置 read_only=`True`.显示外键
# hbook = serializers.PrimaryKeyRelatedField(queryset=BookInfo.objects.all())
# hbook = serializers.PrimaryKeyRelatedField(read_only=True)
# 结果:{'id': 1, 'hname': '吴承恩', 'hgender': 1, 'hcomment': '孙悟空', 'hbook': 1}
#2,添加外键, 来自于关联模型类, __str__的返回值 外键名称
# hbook = serializers.StringRelatedField(read_only=True)
# 结果:{'id': 1, 'hname': '吴承恩', 'hgender': 1, 'hcomment': '孙悟空', 'hbook': '西游记'}
#3,添加外键,关联另外一个序列化器 返回外键关联的所有信息
hbook = BookInfoSerializer(read_only=True)
# 结果:{'id': 1, 'hname': '吴承恩', 'hgender': 1, 'hcomment': '孙悟空', 'hbook': OrderedDict([('id', 1), ('btitle', '西游记'), ('bpub_date', '2021-04-21'), ('bread', 30), ('bcomment', 39), ('is_delete', False)])}
书籍序列化器,关联many
目的:能够序列化书籍的时候,输出关联作者信息
操作流程(book/serializers.py):
class BookInfoSerializer(serializers.Serializer):
id = serializers.IntegerField(label='id',read_only=True)
btitle = serializers.CharField(max_length=20, label='名称')
bpub_date = serializers.DateField(label='发布日期')
bread = serializers.IntegerField(default=0, label='阅读量')
bcomment = serializers.IntegerField(default=0, label='评论数')
is_delete = serializers.BooleanField(default=False, label='逻辑删除')
#1.用书籍查作者:关联英雄主键,many=True,一方中,序列化多方需要加上 (获取id)
# heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
#2.关联英雄,__str__返回值(获取name)
heroinfo_set = serializers.StringRelatedField(read_only=True,many=True)
注意:
many=True,一方中,序列化多方需要加上
==============================================
反序列化
1.1数据类型验证
目的:理解序列化器中的字段,对数据进行校验的过程
常见的字段类型:
CharField:字段串
······
1.2反序列化选项验证
判断max_length等等
- requred:默认是True,必须要传递,除非设置了 default | false | read_only
- read_only: 只读,不进行反序列化
1.3反序列化单个字段验证 :
目的:定义单个字段校验
class BookInfoSerializer(serializers.Serializer):
......
# 反序列化单个字段校验 validate多字段校验,加上字段名是单个字段校验
def validate_btitle(self, value):
# 校验value的内容
if '金瓶' not in value:
raise serializers.ValidationError('书籍不包含金瓶')
return value
- 注意点:
- 固定格式:
def validate_字段名称(self, value):- pass
- 固定格式:
1.4 反序列化,多个字段validate验证
目的:
代码展示:
#多字段校验 def validate(self, attrs): """ :param attrs: 外界传过来的,book_dict :return: """ #1.获取阅读量,评论量 bread = attrs['bread'] bcomment = attrs['bcomment'] #2.判断 if bcomment > bread: raise serializers.ValidationError('评论量大于阅读量') #返回: return attrs
注意:
- 校验不通过的时候一定要抛出异常
1.5反序列化,自定义验证方法
1.6 反序列化,create保存数据
视图层:
from book.serializers import BookInfoSerializer # 1.准备数据 book_dict = { "btitle":"金瓶x-插画版", "bpub_date":"2019-01-01", "bread":17, "bcomment":25 } #2,创建序列化器,校验 serializer = BookInfoSerializer(data=book_dict) # serializer.is_valid() serializer.is_valid(raise_exception=True) #校验不通过,直接报错 # 3.输出 serializer.save()
序列化器代码
from rest_framework import serializers #1.定义序列化器 from book.models import BookInfo class BookInfoSerializer(serializers.Serializer): ...... #实现create方法 def create(self, validated_data): ''' :param validated_data: 校验成功子后的数据 :return: ''' #1.创建book对象,入库 book = BookInfo.objects.create(**validated_data) #2.返回 return book
注意点:
- 当使用序列化器调用sava方法的时候,执行的就是序列化器中的create方法
1.7 反序列化,update更新数据
视图层:
'''===========3.序列化器,反序列化,update更新数据===========''''' from book.serializers import BookInfoSerializer from book.models import BookInfo # 1.准备数据 book_dict = { "btitle":"水浒传", "bpub_date":"2019-01-01", "bread":50, "bcomment":25 } #要更新的数据 book = BookInfo.objects.get(id=1) #2,创建序列化器,校验 serializer = BookInfoSerializer(instance=book,data=book_dict) serializer.is_valid(raise_exception=True) #校验不通过,直接报错 # 3.入库 serializer.save()
序列化器代码:
from rest_framework import serializers #1.定义序列化器 from book.models import BookInfo class BookInfoSerializer(serializers.Serializer): ...... #实现update方法: def update(self, instance, validated_data): ''' :param instance: 外界传过来的值 :param validated_data: 验成功子后的数据 :return: ''' # 1.更新数据 instance.btitle = validated_data['btitle'] instance.bpub_date = validated_data['bpub_date'] instance.bread = validated_data['bread'] instance.bcomment = validated_data['bcomment'] # 2.入库 instance.save() return instance
总结:
*