zoukankan      html  css  js  c++  java
  • DRF序列化和反序列化

    一、自定义序列化组件

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

    二、高级用法

    1.source 的用法

    • 可以指向字段
    • from rest_framework import serializers
      
      
      class 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_obj
              res = models.Book.objects.create(**validated_data)
      
              return res
      
    • 视图层
    • def post(self, request):
              back_dic = {
                  'code': 100,
                  'msg': '',
              }
      
              # 反序列化传入data
              book_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_data
                  back_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
  • 相关阅读:
    移动服务
    CodeForces
    poj1737-----这题有毒
    洛谷P1219 八皇后 (dfs+回溯法)
    codeforces 598D Igor In the Museum(dfs)
    CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)I
    复制构造函数的作用
    codeforces 1102D Balanced Ternary String(贪心+思维)
    学习3DES加密算法笔记
    个人冲刺(六)
  • 原文地址:https://www.cnblogs.com/king-home/p/11126427.html
Copyright © 2011-2022 走看看