当前位置:   article > 正文

drf--source/定制字段的两种方式/反序列化保存/字段校验其他/ModelSerializer_drf serializer 保存指字段

drf serializer 保存指字段

序列化高级用法之source(了解)

  1. # 1 创建了5个表(图书管理的5个)
  2. # 2 对booke进行序列化
  3. # 总结:source的用法
  4. -1 修改前端看到的字段key值---》source指定的必须是对象的属性
  5. book_name = serializers.CharField(source='name')
  6. -2 修改前端看到的value值,---》source指定的必须是对象的方法
  7. 表模型中写方法
  8. def sb_name(self):
  9. return self.name + '_sb'
  10. 序列化类中
  11. book_name = serializers.CharField(source='sb_name')
  12. -3 可以关联查询(得有关联关系)
  13. publish_name = serializers.CharField(source='publish.name')

序列化高级用法之定制字段的两种方式(非常重要)

  1. # 方式一:在序列化类中写
  2. 1 写一个字段,对应的字段类是:SerializerMethodField
  3. 2 必须对应一个 get_字段名的方法,方法必须接受一个obj,返回什么,这个字段对应的value就是什么
  4. # 方式二:在表模型中写
  5. 1 在表模型中写一个方法(可以使用:property),方法有返回值(字典,字符串,列表)
  6. 2 在序列化类中,使用DictField,CharField,ListField

序列化类中写

  1. ### 21 定制字段方式1
  2. class BookSerialzier(serializers.Serializer):
  3. name = serializers.CharField()
  4. price = serializers.CharField()
  5. # 拿出出版社的id和名字和addr,放到一个字典中
  6. # 方式一:SerializerMethodField来定制,如果写了这个,必须配合一个方法get_字段名,这个方法返回什么,这个字段的值就是什么
  7. publish_detail = serializers.SerializerMethodField()
  8. def get_publish_detail(self, book):
  9. # print(obj) # 要序列化的book对象
  10. return {'id': book.publish.pk, 'name': book.publish.name, 'addr': book.publish.addr}
  11. # 练习:拿出所有作者的信息--》多条 [{name:,phone:},{}]
  12. author_list = serializers.SerializerMethodField()
  13. def get_author_list(self, book):
  14. l = []
  15. for author in book.authors.all():
  16. l.append({'id': author.pk, 'name': author.name, 'phone': author.phone, 'age': author.author_detail.age})
  17. return l

表模型中写

  1. ###### ###### ###### ###### ###### 序列化类###### ###### ###### ######
  2. ### 2.2 定制字段方式2
  3. class BookSerialzier(serializers.Serializer):
  4. name = serializers.CharField()
  5. price = serializers.CharField()
  6. # 1 序列化类中这样写
  7. # 2 到表模型中写一个方法,方法名必须叫 publish_detail,这个方法返回什么,这个字段的value就是什么
  8. publish_detail = serializers.DictField()
  9. author_list=serializers.ListField()
  10. ###### ###### ###### ###### ###### 表模型###### ###### ###### ######
  11. class Book(models.Model):
  12. name = models.CharField(max_length=32)
  13. price = models.CharField(max_length=32)
  14. publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True)
  15. authors = models.ManyToManyField(to='Author')
  16. def sb_name(self):
  17. return self.name + '_sb'
  18. @property
  19. def publish_detail(self):
  20. return {'id': self.publish.pk, 'name': self.publish.name, 'addr': self.publish.addr}
  21. def author_list(self):
  22. l = []
  23. for author in self.authors.all():
  24. l.append({'id': author.pk, 'name': author.name, 'phone': author.phone, 'age': author.author_detail.age})
  25. return l

多表关联反序列化保存

  1. # 序列化和反序列化,用的同一个序列化类
  2. -序列化的字段有:name,price , publish_detail,author_list
  3. -反序列化字段:name,price ,publish,author

反序列化之保存

视图类

  1. class BookView(APIView):
  2. def post(self, request):
  3. ser = BookSerialzier(data=request.data)
  4. if ser.is_valid():
  5. ser.save()
  6. return Response({'code': 100, 'msg': '成功'})
  7. else:
  8. return Response({'code': 100, 'msg': ser.errors})

序列化类

  1. class BookSerialzier(serializers.Serializer):
  2. # 即用来做序列化,又用来做反序列化
  3. name = serializers.CharField(max_length=8)
  4. price = serializers.CharField()
  5. # 这俩,只用来做序列化
  6. publish_detail = serializers.DictField(read_only=True)
  7. author_list = serializers.ListField(read_only=True)
  8. # 这俩,只用来做反序列化
  9. publish_id = serializers.IntegerField(write_only=True)
  10. authors = serializers.ListField(write_only=True)
  11. def create(self, validated_data): # {name:西游记,price:88,publish:1,authors:[1,2]
  12. authors = validated_data.pop('authors')
  13. book = Book.objects.create(**validated_data)
  14. book.authors.add(*authors)
  15. book.save()
  16. return book

反序列化之修改

视图类

  1. class BookDetailView(APIView):
  2. def put(self, request,pk):
  3. book=Book.objects.get(pk=pk)
  4. ser = BookSerialzier(data=request.data,instance=book)
  5. if ser.is_valid():
  6. ser.save()
  7. return Response({'code': 100, 'msg': '更新成功'})
  8. else:
  9. return Response({'code': 100, 'msg': ser.errors})

序列化类

  1. class BookSerialzier(serializers.Serializer):
  2. # 即用来做序列化,又用来做反序列化
  3. name = serializers.CharField(max_length=8)
  4. price = serializers.CharField()
  5. # 这俩,只用来做序列化
  6. publish_detail = serializers.DictField(read_only=True)
  7. author_list = serializers.ListField(read_only=True)
  8. # 这俩,只用来做反序列化
  9. publish_id = serializers.IntegerField(write_only=True)
  10. authors = serializers.ListField(write_only=True)
  11. def update(self, instance, validated_data):
  12. authors = validated_data.pop('authors')
  13. for item in validated_data:
  14. setattr(instance, item, validated_data[item])
  15. instance.authors.set(authors)
  16. instance.save()
  17. return instance

反序列化字段校验其他

  1. # 视图类中调用:ser.is_valid()---》触发数据的校验
  2. -4
  3. -字段自己的:max_length,required。。。
  4. -字段自己的:配合一个函数name = serializers.CharField(max_length=8,validators=[xxx])
  5. -局部钩子
  6. -全局钩子

ModelSerializer使用

  1. # 之前写的序列化类,继承了Serializer,写字段,跟表模型没有必然联系
  2. class XXSerialzier(Serializer)
  3. id=serializer.CharField()
  4. name=serializer.CharField()
  5. XXSerialzier既能序列化Book,又能序列化Publish
  6. # 现在学的ModelSerializer,表示跟表模型一一对应,用法跟之前基本类似
  7. 1 写序列化类,继承ModelSerializer
  8. 2 在序列化类中,再写一个类,必须叫
  9. class Meta:
  10. model=表模型
  11. fields=[] # 要序列化的字段
  12. 3 可以重写字段,一定不要放在class Meta
  13. -定制字段,跟之前讲的一样
  14. 4 自定制的字段,一定要在fields中注册一下
  15. 5 class Meta: 有个extra_kwargs,为某个字段定制字段参数
  16. 6 局部钩子,全局钩子,完全一致
  17. 7 大部分请情况下,不需要重写 create和update了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/44700
推荐阅读
相关标签
  

闽ICP备14008679号