Django-drf-序列化器
序列化器
介绍
在Django中,前端传来的数据,一般是JSON格式的数据,获取数据需要通过request.POST.get('xxx)的形式拿到数据,对数据操作完后,返回给前端,也需要转成JSON格式,比较麻烦。
drf中提供了序列化器的功能,解决了这一过程
功能
序列化:把模型对象转为字典,经过response后转成JSON字符串
反序列化:把客户端传来的数据,经过request后转为字典。并完成数据校验功能。序列化器可以把字典转为模型对象。
Serializer
定义一个Serializer类型的序列化器
Serializer类型的序列化器不指定模型表
1 # 新建一个py文件 2 from rest_framework import serializers 3 4 5 class BookSerializer(serializers.Serializer):
# 这里没有指定模型表,但是字段还是要对应 6 # 想序列化哪些字段,就写哪些字段 7 id = serializers.CharField() 8 name = serializers.CharField() 9 price = serializers.CharField() 10 author = serializers.CharField() 11 publish = serializers.CharField()
使用Serializer类型的序列化器
过程:通过ORM从数据库获取数据对象-->调用序列化器,序列化数据-->将序列化的数据返回给前端
在视图类中使用
1 from rest_framework.views import APIView 2 from api import models 3 from api import ser 4 from rest_framework.response import Response 5 6 7 class BoosView(APIView): 8 def get(self,request,pk): 9 # 根据pk拿数据 10 book_queryset = models.Books.objects.filter(id=pk).first() 11 # 调用序列化组件,序列化数据 12 book_ser = ser.BookSerializer(book_queryset) 13 # 序列化对象.data就是序列化后的字典 14 return Response(book_ser.data)
常用选项
- max_length
- min_length
- allow_blank:是否允许为空
- trim_whitespace:是否截断空白字符
- max_value
- min_value
- required:表名该字段在反序列化时必须输入,默认True
- default:反序列化时设置默认值
- allow_null:允许传null,默认False
- validators:该字段使用的验证器
- error_message:包含错误编号与错误信息的字典
- read_only:表名该字段仅用于序列化输出,默认False,若设置为True,在postman中可以看到字段,修改时,不需要传给该字段传值
- write_only:表名该字段段仅用于反序列化输入,默认False,若设置为True,在postman中看不到该字段,修改时,需要给该字段传值
局部钩子函数
from rest_framework.exceptions import ValidationError # 局部钩子 def validate_price(self, data): # 钩子的名字规则:valiedate_字段名,然后接收一个参数 # 如price,价格低于10,校验失败 if float(data) > 10: return data # 钩出来的数据要return else: # 校验失败,抛出异常 raise ValidationError('价格太低')
重写create方法
若序列化类继承了Serializer,客户端请求方式为post的时候,如果去看源码的话,会发现父类BaseSerializer是create方法是直接抛出了异常(NotImplementedError),所以,必须重写create方法
视图类中调用序列化类,通过save方法保存数据
视图类
# 视图类的简单实现
from rest_framework.response import Response from rest_framework.views import APIView class Test(APIView): def post(self, request, *args, **kwargs): response_msg = {'status': 100, 'msg': '新增成功!'} # 新增数据,不需要去数据库查询 book_ser = ser.BookSerializer(data=request.data, many=True) if book_ser.is_valid(): # 校验通过,保存数据 book_ser.save() # 直接调用会报错,需要重写create方法 response_msg['data'] = book_ser.data else: response_msg['status'] = 102 response_msg['msg'] = '修改失败' response_msg['data'] = book_ser.errors return Response(response_msg)
create方法
# 在序列化类中重写create方法
def create(self, validated_data): instance = models.Books.objects.create(**validated_data) return instance
重写update方法
重写update方法的原因同重写create方法的原因,源码中也是直接抛出了异常
视图类
class Test(APIView): def put(self, request, pk): response_msg = {'status': 100, 'msg': '新增成功!'} # 1 获取数据对象 user_list = models.User.objects.filter(pk=pk) # 2 调用序列化类,得到序列化对象 user_ser = ser.UserModelSerializer(user_list, request.data, ) # 3 校验 if user_ser.is_valid(): # 校验通过,爆粗年数据 user_ser.save() # 直接save会报错,因为会去调用update方法,但是源码中update方法是直接跑异常的 response_msg['data'] = user_ser.data else: response_msg['status'] = 103 response_msg['msg'] = '修改失败'
update方法
# 在序列化类中重写
def update(self, instance, validated_data): # instance就是book这个对象 # validate_data就是校验后的数据 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()因为这个save()是django提供的orm的 return instance
全局钩子函数
# 全局钩子 def validate(self,validate_date): author = validate_date.get('author') # 获取校验后的数据 publish = validate_date.get('publish') if author == publish: raise ValidationError('作者名字和出版社一样') else: return validate_date # 钩出来的数据要return
使用validators校验
# ser.py 序列化类中写 def check_author(data): if data.startswith('sb'): raise ValidationError('作者名字不能以sb开头') else: return data class BookSerializer(serializers.Serializer): # 需要序列化哪些字段,就写哪些字段 author = serializers.CharField(validators=[check_author]) # validators后面可以放函数的内存地址,把author对应的数据传进去做校验
ModelSerializer
简介
如果要操作数据库,强烈推荐使用ModelSerializer,因为指定了model和fields,就和数据库的字段对应起来了,不需要每一个字段都通过serializer去创建。并且通过jwt做多用户登录的校验,也可以在序列化类中做,可以直接去模型表中查到对应的数据对象
定义一个ModelSerializer的序列化类
from rest_framework import serializers class BookModelSerializer(serializers.ModelSerializer): class Meta: model = models.Books # 对应上models.py中的模型 fields = '__all__' # 序列化所有字段 # fields = ('name',) # 若不序列化所有字段,写对应的字段名即可,形式为元组或列表
使用
使用序列化类是和Serializer是一样的,区别在于,使用ModelSerializer写序列化类不需要重写create方法和update方法
浙公网安备 33010602011771号