92 序列化 反序列化
主要内容:
1 反序列化(post请求)
a : 提交post请求, 先确定新增的数据结构,
b: 解决序列化和反序列化的字段不统一的情框(序列化器中有的字段, 要序列化的字段必须有.)
required = False, 只序列化, 不走校验
read_only: 只走序列化
write_only: 只走反序列化
c: 对于前端传过来的数据进行校验. 要触发反序列化过程中的create方法,
def create(self, validated_data): # 使用orm操作创建对象 book_obj = models.Book.objects.create(title=validated_data['title'],pub_time=validated_data['pub_time'], category=validated_data['post_category'], publisher_id=validated_data['publisher_id']) book_obj.authors.add(*validated_data['authors_list']) return book_obj
d: 通过验证返回ser_obj.validated_data, 不通过验证返回ser_obj.errors
2 反序列化put请求
a : 提交put请求, 更新数据
b : 反序列化时, 要把反序列化的对象传给对应的instance实例, data = request.data, partial=true部分更新.
c : 反序列化跟新时触发update方法:
def update(self, instance, validated_data): # 使用orm操作编辑对象 print(instance) # 更新的book_obj对象 print(validated_data) # 校验通过的数据 instance.title = validated_data.get('title', instance.title) instance.pub_time = validated_data.get('pub_time', instance.pub_time) instance.category = validated_data.get('post_category', instance.category) instance.publisher_id = validated_data.get('publisher_id', instance.publisher_id) if validated_data.get('authors_list'): instance.authors.set(validated_data['authors_list']) instance.save() return instance
d : 验证通过返回ser_obj.validated_data, 不通过返回ser_obj.errors
e : 单个字段的校验:(权重中间)
def validate_title(self, value): # value就是title的值 对value处理 if "python" not in value.lower(): raise serializers.ValidationError("标题必须含有python") return value
多个字段的校验:(权重最低)
# # 检验多个字段 # def validate(self, attrs): attrs是一个字典 # if 'bad language' not in attrs['title'] and attrs['post_category'] == 1: # return attrs # else: # raise serializers.ValidationError('有敏感信息')
自定义字段校验(权重最高)
def my_validate(value): print('this is validate',value) if '丽丽'in value.lower(): raise serializers.ValidationError('不严谨') return value
注意:给字段配置validators = [my_validate]
class BookSerializer(serializers.Serializer): # # 序列化器中有的字段对象中必须有 # title = serializers.CharField(max_length=32, validators=[my_validate, ])
3 ModelSerializer: 由于自定义序列化器类比较麻烦, 还要写create,update方法, 所以引入了ModelSerializer.
a : 定义一个类继承serializers.ModelSerializer : 会让你这些所有的外键关系变成read_only = True
b : 在类里面定义一个meta类,
类里面的字段model等于表名,
fieds等于所有的字段: fields = "__all__"
depth: 表示层级关系, 最好不要超过三级,
extra_kwargs = {'字段名称','自定义的参数配置信息' }
c : 自定义方法字段: SerializerMethodField() 方法字段
def get_字段名称(self, obj):
obj 每次序列化的模型对象
return 自定义的数据
d : 实例:
自定义校验方法字段, 显示自己需要的内容, 解决depth存在的问题(显示出全部的内容)
authors = serializers.SerializerMethodField() def get_authors(self, obj): print(obj) author_query = obj.authors.all() return [{'id':author.id, 'name':author.name} for author in author_query]
为了解决序列化和反序列化存在的字段不一致问题的解决方案:
authors_info = serializers.SerializerMethodField() def get_authors_info(self, obj): authors_query = obj.authors.all() return [{'id':author.id, 'name': author.name} for author in authors_query]
并在meta中设置extra_kwargs = {'对应的字段':{write_only}: true}(只作为反序列化用)