序列化组件对数据的增删改查
1 写一个序列化的类,继承Serializer
2 在类中写要反序列化的字段,想反序列化哪个字段,就在类中写哪个字段,字段的属性(max_lenth......)
max_length 最大长度
min_lenght 最小长度
allow_blank 是否允许为空
trim_whitespace 是否截断空白字符
max_value 最小值
min_value 最大值
3 在视图类中使用,导入--》实例化得到序列化类的对象,把要修改的对象传入,修改的数据传入
# 两个写法都可以 但是第一个写法必须顺序写对 第二个是指名道姓传(推荐使用)
boo_ser=BookSerializer(book,request.data)
boo_ser=BookSerializer(instance=book,data=request.data) # 建议写成这样
4 数据校验
if boo_ser.is_valid()
5 如果校验通过,就保存
boo_ser.save() # 注意不是book.save() 继承Serializer需要重写update方法
6 如果不通过,逻辑自己写
7 如果字段的校验规则不够,可以写钩子函数(局部和全局)
# 局部钩子
from rest_framework.exceptions import ValidationError
def validate_price(self, data): # validate_字段名 接收一个参数
#如果价格小于10,就校验不通过
# print(type(data))
# print(data)
if float(data)>10:
return data
else:
#校验失败,抛异常
raise ValidationError('价格太低')
# 全局钩子
def validate(self, validate_data): # 全局钩子
print(validate_data)
author=validate_data.get('author')
publish=validate_data.get('publish')
if author == publish:
raise ValidationError('作者名字跟出版社一样')
else:
return validate_data
8 可以使用字段的 validators= 来校验
-写一个函数
def check_author(data):
if data.startswith('sb'):
raise ValidationError('作者名字不能以sb开头')
else:
return data
-配置:validators=[check_author]
author=serializers.CharField(validators=[check_author])
具体写法
# models.py
class Book(models.Model):
id=models.AutoField(primary_key=True)
name=models.CharField(max_length=32)
price=models.DecimalField(max_digits=5,decimal_places=2)
author=models.CharField(max_length=32)
publish=models.CharField(max_length=32)
# ser.py
# from rest_framework.serializers import Serializer # 就是一个类
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
# 需要继承 Serializer
def check_author(data):
if data.startswith('sb'):
raise ValidationError('作者名字不能以sb开头')
else:
return data
class BookSerializer(serializers.Serializer):
# id=serializers.CharField()
name=serializers.CharField(max_length=16,min_length=4)
# price=serializers.DecimalField()
price=serializers.CharField()
author=serializers.CharField(validators=[check_author]) # validators=[] 列表中写函数内存地址
publish=serializers.CharField()
# 局部钩子
def validate_price(self, data): # validate_字段名 接收一个参数
#如果价格小于10,就校验不通过
# print(type(data))
# print(data)
if float(data)>10:
return data
else:
#校验失败,抛异常
raise ValidationError('价格太低')
# 全局钩子
def validate(self, validate_data): # 全局钩子
print(validate_data)
author=validate_data.get('author')
publish=validate_data.get('publish')
if author == publish:
raise ValidationError('作者名字跟出版社一样')
else:
return validate_data
# 重写update方法
def update(self, instance, validated_data):
"""
:param instance: 是book这个对象
:param validated_data: 是检验后的数据
:return:
"""
instance.name = validated_data.get('name')
instance.price = validated_data.get('price')
instance.author = validated_data.get('author')
instance.publish = validated_data.get('publish')
instance.save() # book.save() django的orm提供的
return instance
# 重写create方法
def create(self, validated_data):
instance = models.Book.objects.create(**validated_data)
# instance = models.Book.objects.create(name=validated_data.get('name'),。。。)
# 这是完整写法 当数据中由对不上的信息时就要拆开来写 不能通过 ** 来打散 要具体一个字段一个字段的写
return instance
# views.py
class BookView(APIView):
# 查询一条数据
def get(self, request, pk):
book_obj = models.Book.objects.filter(pk=pk).first()
# 用一个类 毫无疑问也要实例化
# 序列化谁就把谁传过来
book_ser = ser.BookSerializer(book_obj)
# book_ser.data 序列化对象.data就是序列化后的字典
return Response(book_ser.data)
# 修改数据
def put(self, request, pk):
back_dic = {'status': 100, 'msg': '成功'}
book_obj = models.Book.objects.filter(pk=pk).first()
# 得到一个序列化类的对象
# book_ser = ser.BookSerializer(book_obj, request.data)
book_ser = ser.BookSerializer(instance=book_obj, data=request.data)
# 数据验证 返回True表示验证通过
# book_ser.is_valid(raise_exception=True) 验证不通过直接抛异常不走下边了就
book_ser.is_valid(raise)
if book_ser.is_valid():
book_ser.save() # 直接调save方法报错 必须重写update方法
back_dic['data'] = book_ser.data
else:
back_dic['status'] = 101
back_dic['msg'] = '数据校验未通过'
back_dic['data'] = book_ser.errors
return Response(back_dic)
# 新增数据
def post(self, request):
back_dic = {'status': 100, 'msg': '成功'}
# 修改的时候才有instance 新增没有instance 只有data
# book_ser = ser.BookSerializer(request.data) # 报错 因为按位置传第一个参数是instance不能接收data
book_ser = ser.BookSerializer(data=request.data)
# 校验字段
if book_ser.is_valid():
book_ser.save() # 触发序列化类的create方法执行 需要重写create方法
back_dic['data'] = book_ser.data
else:
back_dic['status'] = 102
back_dic['msg'] = '数据校验未通过'
back_dic['data'] = book_ser.errors
return Response(back_dic)
# 删除数据
def delete(self, request, pk):
res = models.Book.objects.filter(pk=pk).delete()
return Response({'status': 100, 'msg': '删除成功!'})
# urls.py
re_path('books/(?P<pk>\d+)/', views.BookView.as_view()),
标签:ser,author,改查,instance,book,增删,validate,序列化,data
From: https://www.cnblogs.com/piggthird/p/17801652.html