一、自定义序列化组件
- 新建一个任意名的py文件,里面导入serlizer
from rest_framework import serializers
- 方法一:继承serializers.Serializer
class BookSerlizer(serializers.Serializer): title = serializers.CharField() price = serializers.IntegerField() pub_date = serializers.DateField() # source 可以指定一个字段也可以指定一个方法 publish = serializers.CharField(source='publish.name') # 获取作者所有的信息,指定SerializerMethodField之后,可以对应一个方法,返回什么内容,authors就是什么内容 authors = serializers.SerializerMethodField(read_only=True) # 对应的方法固定写法get_字段名 def get_authors(self, obj): author_ser = AuthorSerlizer(obj.authors.all(), many=True) return author_ser.data
class BookSerializer(serializers.ModelSerializer): class Meta: model=models.Book # fields=('nid','name') #不能跟fields同时使用 # exclude=['name',] fields=('__all__') #深度是1,官方建议不要超过10,个人建议不要超过3 # depth=1 authors=serializers.SerializerMethodField() def get_authors(self,obj): ret=AuthorSerializer(instance=obj.authors.all(),many=True) return ret.data name=serializers.CharField()
- 视图层
class Books(APIView): def get(self, request): back_dic = { 'code': 100, 'msg': '查询成功', } # 获取所有的图书数据 books = models.Book.objects.all() # print(books) # 序列化数据,many为True序列化多条数据,false序列化一条数据 # instance 序列化,data 反序列化 book_ser = BookSerlizer(instance=books, many=True) # print(book_ser) # 获取序列化后的数据 back_dic['data'] = book_ser.data print(back_dic) return Response(back_dic)
二、高级用法
1.source 的用法
- 可以指向字段
from rest_framework import serializers class BookSerializer(serializers.Serializer): book_name = serializers.CharField(source='book') price = serializers.CharField() # 指向字段名 publish = serializers.CharField(source='publish.name')
class BookSerializer(serializers.ModelSerializer): # 指向方法 book_type =serializers.CharField(source='get_xx_display',read_only=True)
三、序列化总结
-序列化的两种方式 -Serializers:没有指定表模型 -source:指定要序列化哪个字段,可以是字段,可以是方法 - SerializerMethodField的用法 authors=serializers.SerializerMethodField() def get_authors(self,obj): ret=AuthorSerializer(instance=obj.authors.all(),many=True) return ret.data -ModelSerializers:指定了表模型 class Meta: model=表模型 #要显示的字段 fields=('__all__') fields=('id','name') #要排除的字段 exclude=('name') #深度控制 depth=1
-重写某个字段 在Meta外部,重写某些字段,方式同Serializers
四、反序列化
1、使用继承了Serializers序列化类的对象
- 序列化生成器中:自己重写create方法保存数据
def create(self, validated_data): # print('1',validated_data) publish = validated_data.pop('publish') publish_obj = models.Publish.objects.filter(name=publish['name']).first() # print(publish_obj) validated_data['publish'] = publish_obj res = models.Book.objects.create(**validated_data) return res
def post(self, request): back_dic = { 'code': 100, 'msg': '', } # 反序列化传入data book_ser = BookSerlizer(data=request.data) # print('1',request.data) # 校验数是否合法 print(book_ser.is_valid()) # print(book_ser.errors) if book_ser.is_valid(): print(book_ser.validated_data) book_ser.create(book_ser.validated_data) back_dic['data'] = book_ser.validated_data back_dic['msg'] = '新增成功' # print(back_dic) return Response(back_dic)
2、使用继承了ModelSerializers序列化类的对象,反序列化
- 序列化生成器中不需要修改
- 视图函数中直接调用save方法
def post(self,request): bookser=BookSerializer(data=request.data) if bookser.is_valid(): ret=bookser.save() return Response()
五、反序列化的校验——钩子函数
- 局部钩子
def validate_name(self,value): print(value) if value.startswith('sb'): raise exceptions.ValidationError('不能以sb开头') return value
def validate(self,attrs): print(attrs) if attrs.get('price')!=attrs.get('xx'): raise exceptions.ValidationError('name和price相等,不正常') return attrs
-validate_字段名(self,value):
-如果校验失败,抛出ValidationError(抛出的异常信息需要去bookser.errors中取)
-如果校验通过直接return value
-validate(self,attrs)
-attrs所有校验通过的数据,是个字典
-如果校验失败,抛出ValidationError
-如果校验通过直接return attrs