1.rest-framework序列化之Serializer
rest-framework序列化之Serializer步骤 1. 创建一个类,继承Serializer 2. 在类中写要序列化的字段 ''' class BookSerializer(serializers.Serializer): # 序列化表中的某几个字段 固定写法 nid = serializers.CharField() name = serializers.CharField() title = serializers.CharField(source='name') price = serializers.CharField() publish = serializers.CharField(source='publish.email') ''' 3. 在View.py中使用 ''' # 使用序列化 def get(self, request): response = {'status': 100, 'msg': '获取成功'} book_list = Book.objects.all() # 实力化BookSerializer, 将要实力化的数据传入(Queryset对象) # 要是用序列化一定要加many=True book_ser = BookSerializer(book_list, many=True) response['data'] = book_ser.data return Response(response) '''
2. source的用法
1. 指定字段 2. 指定方法 3.深度查询(跨表)
3. rest-framework序列化之ModelSerializer
# 继承ModelSerializer,可以直接指定要序列化的表模型 1. 写一个类, 继承ModelSerializer 2. 在类内部写 class BookSerializer(serializers.ModelSerializer): class Meta: model = models.Book # 指定要序列化的字段 # fields=['nid','name'] # __all__显示全部内容 field ='__all__' # 筛选(注意,不能跟fields连用) exclude = ['name', 'price'] # 深度 depth = 1 重写属性 publish字段,返回出版社的所有信息,包括id,name,email。。。。 #SerializerMethodField配合一个方法,方法的返回值会付给publish publish=serializers.SerializerMethodField() def get_publish(self,obj): # print(type(obj)) # print(obj) return {'id':obj.publish.pk,'name':obj.publish.name}
4. 序列化单条数据
book_ser=BookSerializer(instance=book,many=False)
5. 反序列化之局部和全局钩子(序列化的类一定是继承ModelSerializer的类)
def validate_name(self, value): if value.startswith('sb') raise ValidationError('书名不能以s开头) else: return value #全局钩子函数,对全局字段进行校验 def validate(self,atrr): # print(atrr) name=atrr.get('name') price=atrr.get('price') if name != price: raise ValidationError('错了') else: return a
6. 源码及实现
''' 反序列化局部钩子函数源码: 1. is_valid 2. self.run_validation-(执行Serializer的run_validation) 3. self.to_internal_value(data) 4.(执行Serializer的run_validation:485行) many=True时和many=False时,生成的其实不是一个对象 序列化组件,先调用__new__方法,如果many=True,生成ListSerializer对象,如果为False,生成Serializer对象 序列化组件source源码部分 序列化对象.data方法--调用父类data方法---调用对象自己的to_representation(自定义的序列化类无此方法,去父类找) Aerializer类里有to_representation方法,for循环执行attribute = field.get_attribute(instance) 再去Field类里去找get_attribute方法,self.source_attrs就是被切分的source,然后执行get_attribute方法,source_attrs 当参数传过去,判断是方法就加括号执行,是属性就把值取出来 '''