首页 > DRF序列化和反序列化

DRF序列化和反序列化

一、自定义序列化组件

  • 新建一个任意名的py文件,里面导入serlizer
from rest_framework import serializers
自定义一个类继承serializers,里面写需要序列化的字段
  1. 方法一:继承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
方法二:继承serializers.ModelSerializer
class BookSerializer(serializers.ModelSerializer):class Meta:model=models.Book# fields=('nid','name')#不能跟fields同时使用# exclude=['name',]fields=('__all__')#深度是1,官方建议不要超过10,个人建议不要超过3# depth=1authors=serializers.SerializerMethodField()def get_authors(self,obj):ret=AuthorSerializer(instance=obj.authors.all(),many=True)return ret.dataname=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.dataprint(back_dic)return Response(back_dic)

二、高级用法

1.source 的用法

  • 可以指向字段
from rest_framework import serializersclass 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_objres = models.Book.objects.create(**validated_data)return res
视图层
def post(self, request):back_dic = {'code': 100,'msg': '',}# 反序列化传入databook_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_databack_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

转载于:https://www.cnblogs.com/king-home/p/11126427.html

更多相关:

  • import pickle d = {   'name':'alex',   'role':'police',   'blood': 76,   'weapon':'AK47' } d_dump = pickle.dumps(d) #序列化 print (pickle.loads(d_dump)) #反序列化 f = open('ga...

  •   一年前就已经用过restframework, 当时觉得这个只是给web框架打辅助的, 他能实现的我也都实现(可能没有那么好用, 嘿嘿) 但是我有一种东西叫做效率, 时间就是金钱, 别人造好的就直接用就可以了, 自己其实没必要在去重复.   最近写一个调查问卷系统, 利用了以下知识点   1. django   2. restfra...

  •  本质上说,这并不是二进制序列化的问题,甚至不关序列化的问题。   你想要的是在两个内部结构一致但在不同命名空间(甚至不同项目)的同名类间做类型转换。     这个问题很常见,因为实际工作中经常会有此类需求,但是我们又不可能手动的把每个字段的值都抄来抄去。     解决此问题的方法很多,但都逃不开一个关键思想:A不知道B的存在,B不知...

  • 原文出自:http://www.importnew.com/21517.html 1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个类...

  • ========插入操作========= ====插入单个属性=====--为第一个book节点插入属性name值为"直接插入"set @data.modify('insert (attribute name {"直接插入"})into (/bookstore/book)[1]')/*output:

  • Math.max(...arr);//返回数组最大值 Math.min(...arr);//返回数组最小值Math.max(...objArr.map(o => o.最值字段名));//返回对象数组最大值 Math.min(...objArr.map(o => o.最值字段名));//返回对象数组最小值objArr.sort((pre...

  • 有关函数的官方文档:https://onlinehelp.tableau.com/current/pro/desktop/zh-cn/functions_functions_string.htm 注意事项: 1.记录数:是Tableau自动给每行观测值赋值为1。 2.维度的字段,是不能用于计算的,若是要用于计算,则需要转成度量。 3...

  • 1:删除   连接数据库:新建连接数据库,或者应用转换中已经定义好的数据库。 目标模式:指什么现在还不明确,集群模式?子服务器模式?--要写入数据的表的Schema名称。允许表名中包含“.”是很重要的。  目标表:指定删除记录所对应的表。   提交记录数量:提交之前要改变(删除)的行数   表字段:来源于目标表中的字段。   流字段:...

  • 前言: 前面两篇都是大体介绍流程,有一些配置细节,没有细说,这里用一篇补上。 1、Excel配置项 起始行索引、列头跨行数: 对于自定义的Excel导入模板(有时候模板是由客户提供,模板的规则很乱)比如模板里前面是一些说明,中间是列头,下面还带有数据和说明格式。通过配置起始行索引,以及列头跨行数(0或1都代表一行),则可以解决此类...

  • 1.查询频繁 2.区分度高 例如:数据库表字段:sex 存储:男女,区分度就不高。 3.长度小 索引的长度直接影响索引文件的大小,影响增删改的速度,并间接影响查询速度。 4.尽可能覆盖常用字段   转载于:https://www.cnblogs.com/mingliangzhu/p/6972045.html...