序列化组件(serializers)
序列化组件
序列化目的: 格式化对象成我们要传递的数据
反序列化目的: 校验数据过程
初级版 1.0
注意的点:
- 序列化中传入
数据库中查询出来的queryset对象
,序列化为可以使用Response传递的数据
- 自己定义继承
serializers.Serializer
之后, 里面填写的字段名要与models.py
中对应的表中的字段一样的名字, 因为他是根据反射来查找的 - 序列化可以自定义字段名以及返回值(但是名字一定要不一样),下面代码中有自定义字段
- 反序列化类似于Django中的
forms组件
, 就是用来校验数据的安全性, 有局部钩子,以及全局钩子 - 重写create方法
def create(self, validated_data):
- 反序列化成功之后
反序列化产生的对象.save()
会调用重写的create
方法,完成数据库的数据保存 - 反序列化中的字段必须和前台传过来的字段一一对应,不然如果反序列化中没有,并且
models
中没有默认值,就会保存null
,有默认值传默认值,没默认值保存null
,而不是保存传过来的数据
# 序列化
class MySerializers(serializers.Serializer):
name = serializers.CharField()
color = serializers.IntegerField()
price = serializers.DecimalField(max_digits=10, decimal_places=2)
img = serializers.FileField()
brand = serializers.CharField()
# 自定义字段
hue = serializers.SerializerMethodField()
car_img = serializers.SerializerMethodField()
# 自定义字段的方法:方法名固定格式 get_原表中的字段名(self, obj)
def get_car_img(self, obj):
# 规定自定义字段的返回值
return 'http://127.0.0.1:8000/media/' + str(obj.img)
def get_hue(self, obj):
return obj.get_color_display()
# 反序列化
class MyDeSerializers(serializers.Serializer):
# 反序列化中的规定的数据会得到一个检索
name = serializers.CharField(min_length=3, max_length=8, error_messages={
'min_length': '最短也得三个',
'max_length': '最长也得八个',
'required': '不可以不传'
})
color = serializers.IntegerField()
price = serializers.DecimalField(max_digits=10, decimal_places=2)
brand = serializers.CharField()
# 局部钩子
def validate_name(self, value):
if 'a' in value:
raise serializers.ValidationError({'name': '名字中不可以带有小写a'})
return value
# 全局钩子
def validate(self, attrs):
# attrs就是一个字典
name = attrs.get('name')
if 'b' in name:
raise serializers.ValidationError({'name': '用全局钩子校验名字, 名字不可以有小写b'})
return attrs
# 重写self方法, 保存数据到数据库,validated_data是字典, 检验成功自动保存
def create(self, validated_data):
return models.Car.objects.create(**validated_data)
# view.py
class UserMsg(APIView):
def get(self, request, *args, **kwargs):
car_id = kwargs.get('pk', None)
if car_id:
car_obj = models.Car.objects.filter(pk=car_id).first()
result = MySerializers(car_obj, many=False).data
return Response({'msg': '单查', 'result': result})
else:
# 群查是多个obj [{}, {}],设置many为True
car_obj_lis = models.Car.objects.all()
result = MySerializers(car_obj_lis, many=True).data
return Response({'msg': '群查', 'result': result})
def post(self, request, *args, **kwargs):
post_msg = request.data
obj = MyDeSerializers(data=post_msg) # 返序列化要 data=传过来的数据
if obj.is_valid():
# 如果数据正确
return Response({'msg': 'post请求'})
return Response({'error': obj.errors})