• 02 drf 序列化组件


    一.序列化器(Serializer)

    作用

    1 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
    2 反序列化,讲前端接收到的讯息(数据),通过request之后变成字典
    3 完成数据校验

    如何定义序列化器

    需要使用到Django REST framework 中的 Serializer

    • 自定义一个数据库模型类Book

    # models.py
    class Book(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        price = models.DecimalField(decimal_places=2, max_digits=5)
        author = models.CharField(max_length=32)
        publish = models.CharField(max_length=32)
    • 定义序列化器

      方便演示都使用CharField

    from rest_framework import serializers
    from app01.models import Book


    class BookSerializer(serializers.Serializer):
        id = serializers.CharField()
        name = serializers.CharField()
        price = serializers.CharField()
        author = serializers.CharField()
        publish = serializers.CharField()
    • views.py

    # views.py
    class BookView(APIView):
        def get(self,request,pk):
            book=Book.objects.filter(id=pk).first()
            #用一个类,毫无疑问,一定要实例化
           #要序列化谁,就把谁传过来
           book_ser=BookSerializer(book# 调用类的__init__
            # book_ser.data   序列化对象.data就是序列化后的字典
            return Response(book_ser.data)

    PS:记得配路由

    PS:serializer不是只能为数据库模型类定义,也可以为非数据库模型类的数据定义。serializer是独立于数据库之外的存在。

    常用字段类型:

    1594191496126

    选项参数:

    1594191539366

    通用参数:

    1594191553166

    创建Serializer对象

    Serializer的构造方法为:

    Serializer(instance=None, data=empty, **kwarg)
    • 序列化时,将模型对象传入instance参数

    • 反序列化时,反序列化的数据传入data参数

    • 出了instance和data之外,在构造对象时,可通过context参数另外添加一些参数

    1
    serializer = AccountSerializer(account, context={'request': request})

    通过context参数附加的数据,可以通过Serializer对象的context属性获取。

    1. 使用序列化器的时候一定要注意,序列化器声明了以后,不会自动执行,需要我们在视图中进行调用才可以。

    2. 序列化器无法直接接收数据,需要我们在视图中创建序列化器对象时把使用的数据传递过来。

    3. 序列化器的字段声明类似于我们前面使用过的表单系统。

    4. 开发restful api时,序列化器会帮我们把模型数据转换成字典.

    5. drf提供的视图会帮我们把字典转换成json,或者把客户端发送过来的数据转换字典.

    序列化器的分阶段使用

    阶段1:在客户端请求时,使用序列化器可以完成对数据的反序列化

    阶段2:在服务器响应时,使用序列化器可以完成对数据的序列化

    序列化器的简单使用总结

    1 写一个序列化的类,继承Serializer
    2 在类中写要序列化的字段,想序列化哪个字段,就在类中写哪个字段
    3 在视图类中使用,导入--》实例化得到序列化类的对象,把要序列化的对象传入
    4 序列化类的对象.data   是一个字典
    5 把字典返回,如果不使用rest_framework提供的Response,就得使用JsonResponse

    序列化组件修改数据

    1 先写一个序列化的类,继承Serializer
    2 在类中书写反序列化的字段,需要反序列化哪个字段,就在类中写哪个字段
    3 在视图类中使用,导入——》实例化得到序列化类的对象,把要修改的对象传入,修改的数据传入
    boo_ser=BookSerializer(book,request.data)
        boo_ser=BookSerializer(instance=book,data=request.data)
    4 数据校验
    if boo_ser.is_valid()
    5 通过就保存起来
    boo_ser.save()
    6 不通过就报错误信息
            response_msg['status'] = 101
                response_msg['msg'] = '数据错误'
                response_msg['data'] = book_ser.errors
            return Response(response_msg)

    序列化组件增加数据

       def put(self,request,pk):
            response_msg={'status':100,'msg':'成功'}
            # 找到这个对象
           book = Book.objects.filter(id=pk).first()
            # 得到一个序列化类的对象
           # boo_ser=BookSerializer(book,request.data)
            boo_ser=BookSerializer(instance=book,data=request.data)

            # 要数据验证(回想form表单的验证)
           if boo_ser.is_valid():  # 返回True表示验证通过
               boo_ser.save()  # 报错
               response_msg['data']=boo_ser.data
            else:
                response_msg['status']=101
                response_msg['msg']='数据校验失败'
                response_msg['data']=boo_ser.errors

            return Response(response_msg)

    PS:需要重写update和create方法(在序列化器中)

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name')
        instance.price = validated_data.get('price')
        instance.author = validated_data.get('author')
        instance.publish = validated_data.get('publish')
        instance.save()
        return instance

    def create(self, validated_data):
        instance = Book.objects.create(**validated_data)
        return instance

    局部钩子

    # 局部钩子
        def validate_price(self, data):   # validate_字段名 接收一个参数
               #如果价格小于10,就校验不通过
               if float(data)>10:
                    return data
                else:
                    #校验失败,抛异常
                   raise ValidationError('价格太低')
             # 全局钩子

    全局钩子

      def validate(self, validate_data):   # 全局钩子
               print(validate_data)
                author=validate_data.get('author')
                publish=validate_data.get('publish')
                if author == publish:
                    raise ValidationError('作者名字跟出版社一样')
                else:
                    return validate_data

    read_only和write_only

    read_only   表明该字段仅用于序列化输出,默认False,如果设置成True,postman中可以看到该字段,修改时,不需要传该字段
    write_only 表明该字段仅用于反序列化输入,默认False,如果设置成True,postman中看不到该字段,修改时,该字段需要传

    # 以下的了解即可
    required 表明该字段在反序列化时必须输入,默认True
    default 反序列化时使用的默认值
    allow_null 表明该字段是否允许传入None,默认False
    validators 该字段使用的验证器
    error_messages 包含错误编号与错误信息的字典

    模型类序列化器

    class BookModelSerializer(serializers.ModelSerializer):
        class Meta:
            model=Book  # 对应上models.py中的模型
           fields='__all__'
            # fields=('name','price','id','author') # 只序列化指定的字段
           # exclude=('name',) #跟fields不能都写,写谁,就表示排除谁
           # read_only_fields=('price',)
            # write_only_fields=('id',) #弃用了,使用extra_kwargs
            extra_kwargs = {  # 类似于这种形式name=serializers.CharField(max_length=16,min_length=4)
                'price': {'write_only': True},
           }
           
    # 其他使用一模一样
    #不需要重写create和updata方法了

  • 相关阅读:
    ABP 数据库 -- ABP&EF中的多表、关联查询
    C# List集合基础操作
    C# ABP 允许跨域请求
    异或运算、与运算、或运算 运用在 多项选择题
    C# ABP 配置连接数据库&创建表
    C# ABP WebApi与Swagger UI的集成
    C# 深入了解泛型
    8、SpringBoot+Mybatis整合------参数取值方式
    7、SpringBoot+Mybatis整合------PageHelper简单分页
    6、SpringBoot+Mybatis整合------参数传递
  • 原文地址:https://www.cnblogs.com/bailongcaptain/p/13267260.html
Copyright © 2020-2023  润新知