zoukankan      html  css  js  c++  java
  • DRF 2 序列化器

    2 序列化器

    作用

    1. 序列化,把模型对象转换成字典

      因为def规范要求response需要返回json格式数据,但是查表得到的是一个表模型对象,而python中对象不能被json序列化,所以需要将对象转成字典(手动实现:一个个取对象的属性用for生成字典)再用response处理(内部自动序列后)返回json格式数据

    2. 反序列化 把字典格式的数据写入表模型中

      客户端发送过来的数据,经过request处理后得到一个字典,虽然用**将字典传入可以快速写入数据,但是写入之前先要判断k与字段名知否对应,序列化器则简化了这两个步骤.

    2.1 半自动序列化器 Serializer

    from rest_framework import serializers
    
    # 声明序列化器,所有的序列化器都要直接或者间接继承于 Serializer
    class StudentSerializer(serializers.Serializer):
        """商品信息序列化器"""
    
        name = serializers.CharField()
        price = serializers.IntegerField()
        
        
    	一,序列化时:没啥可说的,就是把模型对象转换成字典
        
        二,反序列化时:
            1,先判断接受的数据是否符合参数规则
            2,符合规则的数据放入到validate_data中
            3,修改表模型对象属性,手动操作,重写updata或create方法,因为Serializer没有提供这两个方法
            def update (self,instance,validate_data):
            	instance.name=validate_data.get('name')
                instance.price=validate_data.get('price')
                instance.save() #表模型对象的save方法
                
            def create(self,instance,validate_data):
                models.Book.object.create(**validate_data)
                
            4,调用序列化器的.save()方法内部会调用update或save方法,数据就存入表中了
            
         三,反序列化的额外方法:
            1)validators法:该方法将和校验函数配置在参数里
                name = serializers.CharField(validators=[check_func])
                
                def check_func(data):
                    业务逻辑代码
                    
            2)局部校验和全局校验两种方法:
                局部校验钩子函数:函数命名规则--validate_字段名
                    def validate_price(self,data):
                    	业务逻辑代码
                
                全局校验钩子函数:函数命名规则--validate
                    def validate(self,validated_data):
                        业务逻辑代码
            如果校验不通过就要抛出异常:
                raise ValidationError('错误提示')
                
            校验通过就返回数据
            
          四,返回和接收的数据的字段不一样怎么办?参数中加入下面两个参数
        	name = serializers.CharField(read_only = True)
        	read_only = True #只读字段
            write_only = True #只写字段
            
          五,如何自定义返回查表结果?Serializer高级用法
        	# source的使用
            1 可以改字段名字  xxx=serializers.CharField(source='title') #title是表中有的字段
            2 可以跨表publish=serializers.CharField(source='publish.email')#跨表的前提是publish是			外键字段,而且email在publish表中
            3 可以执行方法pub_date=serializers.CharField(source='test') #test是Book表模型中的方法
    
    
        	# SerializerMethodField()更强的自定义输出结果
            1 它需要有个配套方法,方法名叫get_字段名,返回值就是要显示数据
            authors=serializers.SerializerMethodField() 
            
            def get_authors(self,instance):
                # book对象
                authors=instance.authors.all()  # 取出所有作者
                ll=[] #编辑自定义的查询结果
                for author in authors:
                    ll.append({'name':author.name,'age':author.age})
                return ll
        	
        
                
               
    

    2.2 全自动序列化器ModelSerializer

    提供了create()和update()方法,可以直接调用了,但是不会自动执行
    (如果继承了UpdateModelMixin,CreateModelMixin,这两个类会去验证数据是否合法并调用create()和update()方法)

    使用:

    1.我们创建一个BookInfoSerializer
    
    class BookInfoSerializer(serializers.ModelSerializer):
        """图书数据序列化器"""
        class Meta:
            model = BookInfo
            fields = (name,)
    model指明参照哪个模型类
    fields指明为模型类的哪些字段生成
    
    
    2.指定字段
        #fields详解:
            fields内可以填入有1(model字段),2(model中定义的方法),3(SerializerMethodField()字段),4(子序列化字段)
            1)表模型对应的字段:直接序列化字段的内容,若是外键字段返回一个对象的打印结果,需要在表模型中重写				__str__方法
            2)model中定义的方法:序列化方法的结果,一般用来定制外键字段输出的信息,
            3)SerializerMethodField()字段 和2.1的使用方法一样,需要额外添加字段	
            4)子序列法 直接引用其他序列化器的结果,也需要额外添加字段
            class BookInfoSerializer(serializers.ModelSerializer):
                """图书数据序列化器"""
                authors=serializers.SerializerMethodField()
                authors=AuthorSerializer() #子序列化需要添加的字段
                class Meta:
                    model = BookInfo
                    fields = (name,authors,)	
            
    注意:不是实实在在存在表中的字段都需要设置为只读,否则写入时报错!
        read_only_fields = ('id',)
            
    3.添加额外参数 extra_kwargs
    	我们可以使用extra_kwargs参数为ModelSerializer添加或修改原有的选项参数
    
        class BookInfoSerializer(serializers.ModelSerializer):
            """图书数据序列化器"""
            class Meta:
                model = BookInfo
                fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
                extra_kwargs = {
                    'bread': {'min_value': 0, 'required': True},
                    'bcomment': {'min_value': 0, 'required': True},
                }
    
    

    2.3 序列化器的使用

    基本用法

    基于APIView视图类的使用

    1) 先查询出一个对象

    from students.models import Student
    
    student = Student.objects.get(id=3)
    

    2) 构造序列化器对象

    from .serializers import StudentSerializer
    
    serializer = StudentSerializer(instance=student)
    

    3)获取序列化数据

    通过data属性可以获取序列化后的数据,是一个字典

    serializer.data
    # {'id': 4, 'name': '小张', 'age': 18, 'sex': True, 'description': '猴赛雷'}
    

    说明

    1)用于序列化时,只传一个instance参数,默认第一个参数

    2)用于反序列化时,只传入data参数

    1. 同时传入 instance,data字段进行修改操作

    4)如果要被序列化的是包含多条数据的查询集QuerySet,可以通过添加many=True参数补充说明

    5)除了instance和data参数外,在构造Serializer对象时,还可通过context参数额外添加数据,如

    serializer = AccountSerializer(account, context={'request': request})
    
    基于GenericAPiView配合Mixin类的使用
    见4.3
    

    高级用法

    1.重写serializer的validate方法,通过context参数将数据传入序列化类中,实现复杂的业务逻辑在序列化类里判断

    2.重写create或update方法实现一次性操作多张表,或其他业务需求

  • 相关阅读:
    apache安装
    docker搭建redis主从
    docker安装
    sklearn工具-绪论
    数学基础-矩阵和线性代数
    数学基础-概率论与贝叶斯先验
    数学基础-数学分析
    数据科学包——Matplotlib
    数据科学包——pandas
    数据科学包——numpy
  • 原文地址:https://www.cnblogs.com/Franciszw/p/13552259.html
Copyright © 2011-2022 走看看