drf——序列化之source(了解)、定制字段的两种方式(重要)、多表关联反序列化保存、反序列化字段校验、ModelSerializer使用
2023/5/19 1:22:13
本文主要是介绍drf——序列化之source(了解)、定制字段的两种方式(重要)、多表关联反序列化保存、反序列化字段校验、ModelSerializer使用,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1 序列化高级用法之source(了解)
# 1.创建了5个表(图书管理的5个) # 2.对book进行序列化 # 总结:source的用法 1.修改前端看到的字段key值--->source指定的必须是对象的属性 book_name = serialiazers.CharField(source='name') 2.修改前端看到的value值 ---> source指定的必须是对象的方法 表模型中写方法 def sb_name(self): return self.name = '_sb' 序列化类中 book_name = serializers.CharField(source='sb_name') 3.可以关联查询(得有关联关系) publish_name = serializers.CharField(source='publish.name')
2 序列化高级用法之定制字段的两种方式(非常重要)
# 方式一:在序列化类中写 1.写一个字段 对应的字段类是:SerializerMethodField 2.必须对应一个get_字段名的方法 方法必须接收一个obj 返回什么 这个字段对应的值就是什么 # 方式二:在模型层中写 1.在表模型中写一个方法(可以使用:property),方法有返回值(字典,字符串,列表) 2.在序列化类中 使用DictField,CharField,ListField
2.1在序列化类中写
class BookSerializer(serializer.Serializer): name = serializer.CharField() price = serializers.CharField() # 拿出出版社的id和名字和addr,放到一个字典中 # 方式一:SerializerMethodField来定制,如果写了这个,必须配合一个方法get_字段名,这个方法返回什么,这个字段的值就是什么 publish_detail = serializers.SerializerMethodField() def get_publish_detail(self,book): # print(obj) # 要序列化的book对象 return {'id': book.publish.pk, 'name': book.publish.name, 'addr': book.publish.addr} # 练习:拿出所有作者的信息--》多条 [{'name':'','phone':''},{}] author_list = serializers.SerializerMethodField() def get_author_list(self,book): l = [] for item in book.authors.all() l.append({'id': author.pk, 'name': author.name, 'phone': author.phone, 'age': author.author_detail.age}) return l
2.2表模型中写
############################### 序列化类 ############################# class BookSerializer(serializers.Serializer): name = serializers.CharField() price = serializers.CharField() # 1.序列化类中这样写 # 2.到模型表中写一个方法 方法名必须叫publish_detail 这个方法返回什么 这个字段的value就是什么 publish_detail = serializers.DictField() author_list = serializers.ListField() ################################ 表模型 ########################### class Book(models.Model): name = models.CharField(max_length=32) price = models.CharField(max_length=32) publish = models.ForeignKey(to='Publish', on_delete=models.SET_NULL, null=True) authors = models.ManyToManyField(to='Author') @property def publish_detail(self): return {'id': self.publish.pk, 'name': self.publish.name, 'addr': self.publish.addr} def author_list(self): l = [] for author in self.authors.all(): l.append({'id': author.pk, 'name': author.name, 'phone': author.phone, 'age': author.author_detail.age}) return l
3 多表关联反序列化保存
#序列化和反序列化 用的同一个序列化类 序列化的字段有:name,price , publish_detail,author_list 反序列化字段:name,price ,publish,author
3.1反序列化之保存
视图类
class BookView(APIView): def post(self, request): ser = BookSerialzier(data=request.data) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '成功'}) else: return Response({'code': 100, 'msg': ser.errors})
序列化类
class BookSerialzier(serializers.Serializer): # 即用来做序列化,又用来做反序列化 name = serializers.CharField(max_length=8) price = serializers.CharField() # 这俩,只用来做序列化 publish_detail = serializers.DictField(read_only=True) author_list = serializers.ListField(read_only=True) # 这俩,只用来做反序列化 publish_id = serializers.IntegerField(write_only=True) authors = serializers.ListField(write_only=True) def create(self, validated_data): # {name:西游记,price:88,publish:1,authors:[1,2] authors = validated_data.pop('authors') book = Book.objects.create(**validated_data) book.authors.add(*authors) book.save() return book
3.2反序列化之修改
视图类
class BookDetailView(APIView): def put(self, request,pk): book=Book.objects.get(pk=pk) ser = BookSerialzier(data=request.data,instance=book) if ser.is_valid(): ser.save() return Response({'code': 100, 'msg': '更新成功'}) else: return Response({'code': 100, 'msg': ser.errors})
序列化类
class BookSerialzier(serializers.Serializer): # 即用来做序列化,又用来做反序列化 name = serializers.CharField(max_length=8) price = serializers.CharField() # 这俩,只用来做序列化 publish_detail = serializers.DictField(read_only=True) author_list = serializers.ListField(read_only=True) # 这俩,只用来做反序列化 publish_id = serializers.IntegerField(write_only=True) authors = serializers.ListField(write_only=True) def update(self,instance,validated_data): authors = validated_data.pop('authors') for item in validated_data: setattr(instance,item,validated_data['item']) instance.authors.set(authors) instance.save() return instance
4 反序列化字段校验其他
# 视图类中调用:ser.is_valid()--->触发数据的校验 4层 -字段自己的:max_length,required。。。 -字段自己的:配合一个函数name = serializers.CharField(max_length=8,validators=[xxx]) -局部钩子 -全局钩子
5 ModelSerializer使用
# 之前写的序列化类 继承了Serializer 写字段 跟表模型没有必然联系 class XXSerializer() id=serializer.CharField() name=serializer.CharField() XXSerialzier既能序列化Book,又能序列化Publish # 现在学的ModelSerializer,表示跟表模型一一对应,用法跟之前基本类似 1 写序列化 继承ModelSerializer 2 在序列化类中 再写一个类 必须交 class Meta: model=表模型 fields=[] # 要序列化的字段 3 可以重写字段 一定不要放在class Meta下 定制字段 跟上面一样 4 自定制的字段 一定要在fields中注册一下 5 class Meta: 有个extra_kwargs 为某个字段定制字段参数 6 局部钩子 全局钩子 完全一致 7 大部分情况下 不需要重写 create和update了
这篇关于drf——序列化之source(了解)、定制字段的两种方式(重要)、多表关联反序列化保存、反序列化字段校验、ModelSerializer使用的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-15PingCAP 黄东旭参与 CCF 秀湖会议,共探开源教育未来
- 2024-05-13PingCAP 戴涛:构建面向未来的金融核心系统
- 2024-05-09flutter3.x_macos桌面os实战
- 2024-05-09Rust中的并发性:Sync 和 Send Traits
- 2024-05-08使用Ollama和OpenWebUI在CPU上玩转Meta Llama3-8B
- 2024-05-08完工标准(DoD)与验收条件(AC)究竟有什么不同?
- 2024-05-084万 star 的 NocoDB 在 sealos 上一键起,轻松把数据库编程智能表格
- 2024-05-08Mac 版Stable Diffusion WebUI的安装
- 2024-05-08解锁CodeGeeX智能问答中3项独有的隐藏技能
- 2024-05-08RAG算法优化+新增代码仓库支持,CodeGeeX的@repo功能效果提升