21 序列化器(一)
作用
1, 反序列化: 将json(dict)数据, 转成模型类对象
①: 校验
②: 入库
2, 序列化: 将模型类对象, 转成json(dict)数据
校验
①: 校验
1, 字段类型校验
2, 字段选项校验
3, 单字段校验, 方法
4, 多字段校验, 方法
5, 自定义校验, 方法
入库
1、create
2、update
定义
定义序列化器:
1, 定义类, 继承自Serializer
2, 编写字段名称, 和模型类一样
3, 编写字段类型, 和模型类一样
4, 编写字段选项, 和模型类一样
read_only: 只读
label: 字段说明
使用序列化器
创建
1、在应用(app)中创建serialzers.py文件
序列化字段 写入serialzers.py 文件中
from rest_framework import serializers
class BookInfoSerializer(serializers.Serializer):
id = serializers.IntegerField(label='id',read_only=True)
btitle = serializers.CharField(max_length=20,label='名称')
bpub_dae = serializers.DateField(label='发表日期')
bread = serializers.IntegerField(default=0,label='阅读量')
bcomment = serializers.IntegerField(default=0,label='评论量')
is_delete = serializers.BooleanField(default=False,label='逻辑删除')
使用序列化器中的序列化 :修改原来的 view.py 的文件
from django import http
import json
# 创建视图
from django.views import View
from ..models import BookInfo
from ..serializers import BookInfoSerializer
class BookInfoView(View):
def get(self,request):
'''获取所有书籍'''
# 查询所有书籍
books = BookInfo.objects.all()
# [, , , ]
# 数据转换
'''
book_list=[]
for book in books:
book_dict = {
'id':book.id,
'btitle':book.btitle,
'bpub_date':book.bpub_date,
'bread':book.bread,
'bcomment':book.bcomment,
'is_delete':book.is_delete
}
book_list.append(book_dict)
'''''
serializers = BookInfoSerializer(instance=books,many=True)
# 返回json格式数据 safe=False可以安全返回非字典
return http.JsonResponse(serializers.data,safe=False)
def post(self,request):
dict_data=json.loads(request.body.decode())
# 检验参数
# 数据入库
book = BookInfo.objects.create(**dict_data)
#返回book是一个字典 入库后的数据
# 返回响应
'''
book_dict = {
'id': book.id,
'btitle': book.btitle,
'bpub_date': book.bpub_date,
'bread': book.bread,
'bcomment': book.bcomment,
'is_delete': book.is_delete
}
'''''
serializers = BookInfoSerializer(instance=book)
return http.JsonResponse(serializers.data,status=201)
class BookInfoDetailView(View):
def get(self,request,id):
# 通过id获取
book = BookInfo.objects.get(pk=id)
# 返回数据
'''
book_dict = {
'id':book.id,
'btitle':book.btitle,
'bpub_date':book.bpub_date,
'bread':book.bread,
'bcomment':book.bcomment,
'is_delete':book.is_delete
}
'''''
serializers = BookInfoSerializer(instance=book)
return http.JsonResponse(serializers.data,status=200)
# 更新单个
def put(self,request,id):
# 获取更新结果和根据id获取该项
book_data = json.loads(request.body.decode())
# book = BookInfo.objects.get(id=id)
# 校验参数(省略)
# 更新数据
BookInfo.objects.filter(id=id).update(**book_data)
# 返回数据
book = BookInfo.objects.get(id=id)
'''
book_dict = {
'id': book.id,
'btitle': book.btitle,
'bpub_date': book.bpub_date,
'bread': book.bread,
'bcomment': book.bcomment,
'is_delete': book.is_delete
}
'''''
serializers = BookInfoSerializer(instance=book)
return http.JsonResponse(serializers.data)
# 删除单个
def delete(self,request,id):
book = BookInfo.objects.get(id=id)
book.delete()
return http.JsonResponse({'msg':'删除成功'},status=204)
其中 many=True 是运行序列化多个对象 默认是False
在 postman中发送请求看看是否成功
如果要序列化外键呢?即英雄外键绑定书籍 我们查询书籍想要把英雄查询出来
序列化器中
class BookInfoSerializer(serializers.Serializer):
......
heroinfo_set = serializers.StringRelatedField(read_only=True,many=True)
# 或者下面
# heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True,many=True)
如果我们查询的是英雄 我们知道是哪本书籍的呢
# hbook = serializers.PrimaryKeyRelatedField(read_only=True)
# hbook = serializers.PrimaryKeyRelatedField(queryset=BookInfo.objects.all()) # 关联自定义的 模块__str__函数返回值 可以自定义 在书籍的模型中的__str__方法自定义 # hbook = serializers.StringRelatedField(read_only=True) # 关联整个对象 hbook = BookInfoSerializer()
序列化器中的反序列化
定义:json转换模型对象 ,json是接口发送的json格式给服务器转换成模型对象 ,其中接口发送的json就是写 而 模型对象转换为json就是读
json==>模型类==>写==>反序列化
模型类==>json==>读==>序列化
步骤
反序列化==>校验字段==>入库
输入 python manage.py shell
粘贴
# 模拟获取接口传入数据
book_dict = {
'btitle':'jin瓶梅x',
'bpub_date':'2000-1-12',
'bread':10,
'bcomment':'a'
}
# 导入序列化器
from book.serializers import BookInfoSerializer
# 反序列化
serializer = BookInfoSerializer(data=book_dict)
# 校验规则如果校验不通过则抛出异常
serializer.is_valid(raise_exception=True)
#打印 反序列化结果
print(serializer.data)
BookInfoSerializer(instance=xx) 是序列化
BookInfoSerializer(data=xx)是反序列化
校验是校验什么呢?
校验传入的字段是否满足模型类中设置的要求!
例如:是否是字符串、数字、布尔类型 长度是否满足要求,只读、只写等等
那么我们也可以在设置校验规则 开头说明有五种校验规则
1 、单字段校验 -- 加入的书名必须包含 jin瓶 两个字
class BookInfoSerializer(serializers.Serializer):
......
# 单字段验证 判断是否书名是否存在 jin瓶
# 固定格式 validate_字段名()
def validate_btitle(self,value):
'不管return 什么都是验证成功 所以得抛出异常'
if 'jin瓶' not in value:
raise serializers.ValidationError('书名不包括jin瓶')
return value
2、多字段校验 -- 阅读量必须大于评论量
class BookInfoSerializer(serializers.Serializer):
.......
# 阅读量要大于评论量 函数名是必须是这样子写
def validate(self, attrs):
'''
:param attrs: 是 books 外面data的值
:return:
'''
# 获取
bread = attrs['bread'] #阅读量
bcomment = attrs['bcomment'] #评论量
# 比较
if bcomment>bread:
raise serializers.ValidationError('评论量不能大于阅读量')
return attrs
3、自定义检验 -- 因为比较少用

其中方法函数不在序列化器中
入库
book_dict = {
'btitle':'jin瓶梅x',
'bpub_date':'2000-1-12',
'bread':100,
'bcomment':20
}
# 校验规则
from booktest.serializers import BookInfoSerializer
serializer = BookInfoSerializer(data=book_dict)
serializer.is_valid(raise_exception=True)
#
serializer.save()
save() 现在调用的是create方法但是序列化器中我们并没有写create方法 这样中运行你可以试试看会报 找不到create函数
create
我们现在就来写一个create方法
class BookInfoSerializer(serializers.Serializer):
....
def create(self, validated_data):
'''
:param validated_data: 是检验后的数据
:return:
'''
book = BookInfo.objects.create(**validated_data)
# print(book)
return book
update
更新 传入一个对象 来替换现有的一个对象
book_dict = {
'btitle':'jin瓶梅x',
'bpub_date':'2000-1-12',
'bread':100,
'bcomment':20
}
from book.models import BookInfo
book = BookInfo.objects.get(id=1)
# 校验规则
from booktest.serializers import BookInfoSerializer
serializer = BookInfoSerializer(instance = book,data=book_dict)
serializer.is_valid(raise_exception=True)
#
serializer.save()
这时save()就会调用update函数 只要序列化器传入instance和data save()就会调用update函数
我们来写一个
class BookInfoSerializer(serializers.Serializer):
....
def update(self, instance, validated_data):
instance.btitle = validated_data['btitle']
instance.bpub_date=validated_data['bpub_date']
instance.bread = validated_data['bread']
instance.bcomment = validated_data['bcomment']
instance.save()
return instance

浙公网安备 33010602011771号