• 序列化组件


    1,序列化

    1. 声明序列化器,具体代码如下
    from rest_framework import serializers
    from DrfDemo.models import Book
    
    # -----------------------这是第一版get请求的serializers------------------
    class PublisherSerializrs(serializers.Serializer):
        id = serializers.IntegerField()
        title = serializers.CharField(max_length=32)
    
    
    # 在类中写了字段,书写校验这个字段
    class AuthorSerializer(serializers.Serializer):
        id = serializers.IntegerField()
        name = serializers.CharField(max_length=32)
    
    
    class BookSerializer(serializers.Serializer):
        id = serializers.IntegerField()
        title = serializers.CharField(max_length=32)
        pub_time = serializers.DateField()
        category = serializers.CharField(source="get_category_display")
        # 关于外键的验证用外键字段名Serializers的方法
        publisher = PublisherSerializrs()
        authors = AuthorSerializer(many=True)
    1. 业务逻辑处理部分
    序列化代码

    2,反序列化,post请求

    1. 确定新增的数据结构
    2. 序列化器
      1. 正序和反序字段不统一
      2. required= False  只序列化,不走校验
      3. read_only=True 只序列化用
      4. write_only =True 只反序列化用
      5. 重写create方法
    3. 验证通过返回ser_obj.validated_data
    4. 验证不通过返回ser_obj.errors 

    3,反序列化,put/patch请求

    1. 重写update方法
    2. ser_obj = Bookserializer(instance=obj, data=request.data, partial=True)
    3. 验证通过返回ser_obj.validated_data
    4. 验证不通过返回ser_obj.errors
    正序,反序字段不统一

     4,验证

    1. 自定义的验证 权重111
      • def_my_validate(value):
        • 不通过抛异常:raise serializer.ValidationError("错误信息")
        • 通过return value
        • 配置----->给字段加validations=[My_validate]
    1. 单个字段的验证 权重222
      • def validate_字段名称(self, value):
        • 不通过raise serializers.ValidationErrors("错误信息")
    1. 多个字段的验证 权重333
      • def validate(self, attrs):
        • attrs是所有字段组成的字典
        • 不通过raise serializers.ValidationError("错误信息")
    校验器
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from DrfDemo.models import Book
    from DrfDemo.serializers import BookSerializer
    
    
    class BookView(APIView):
        # 定义一个get请求的额度方法
        def get(self, request):
            # 从数据库中获取数据
            book_queryset = Book.objects.all()
            print()
            # 用序列化器进行序列化
            ser_obj = BookSerializer(book_queryset, many=True)
            # 既然用rest_frame框架就用人家提供的response
            return Response(ser_obj.data)
    
        # 手写一个post获取数据的方法(新增)
        def post(self, request):
            # 1,确定数据类型以及数据结构
            # 2,对前端妹子传过来的的数据进行校验
            book_obj = request.data  # 获取前端传过来的数据
            print("前端传过来的数据:", book_obj, type(book_obj))
            # 把获取到的数传给BookSerializer方法里进行校验
            ser_obj = BookSerializer(data=book_obj)
            # 如果通过校验
            if ser_obj.is_valid():
                print("通过校验的数据:", ser_obj)
                # 把通过校验的更新到数据库中
                ser_obj.save()
                print(456)
                # 更新完以后把更新后的数据展示到前端
                return Response(ser_obj.validated_data)
            # 如果没通过校验就返回错误信息,错误信息都封装在了ser_obj中
            return Response(ser_obj.errors)
    
    
    # 编辑CBV
    class BookEditView(APIView):
        # 手写一个get请求
        def get(self, request, id):
            # 获取到要更新数据的对象
            book_obj = Book.objects.filter(id=id).first()
            ser_obj = BookSerializer(book_obj)  # 单个对象的时候不用many=True
            # 返回这个数据经过序列化的数据
            return Response(ser_obj.data)
    
        # 手写一个put更新的方法
        def put(self, request, id):
            book_obj = Book.objects.filter(id=id).first()
            # 把筛选到的对象去调用BookSerializer方法
            ser_obj = BookSerializer(instance=book_obj, data=request.data, partial=True)
            print(ser_obj)
            if ser_obj.is_valid():
                ser_obj.save()
                print(123)
                # 返回经过更新到数据库的数据
                return Response(ser_obj.validated_data)
            # 否则报错误
            return Response(ser_obj.errors)
    
    序列化代码

    5,序列化器的ModelSerializer

    1. 定义一个序列化器继承(serializers.ModelSerializer)
    2. 源信息的配置
      1. class Meta
      2. fileds = "__all__"
      3. exclude = ["字段名",]
      4. depth = 1       (depth会让所有的外键关系字段都变成read_only = True)
      5. extra_kwargs= {"默认的字段名称":{自定义的参数配置信息}}
      6. SerializerMethodField()方法字段
        • def get_字段名称(self, obj):
          • obj 每次序列化的模型对象
          • return 自定义的数据
    ModelSerializer
    def my_validate(value):
        print(value)
        if "雪雪" in value.lower():
            raise serializers.ValidationError("这太暴露了")
        return value
    
    class PublisherSerializrs(serializers.Serializer):
        id = serializers.IntegerField()
        title = serializers.CharField(max_length=32)
    
    
    # 在类中写了字段,书写校验这个字段
    class AuthorSerializer(serializers.Serializer):
        id = serializers.IntegerField()
        name = serializers.CharField(max_length=32)
    
    
    # 重新写Book的序列化器
    class BookSerializer(serializers.Serializer):
        # 1,不是进行必须的序列化和反序列化
        id = serializers.IntegerField(required=False)  # 表示不是必须进行序列化
        # 2,默认的字段,不管是序列化,还是反序列化都需要通过这几个字段
        title = serializers.CharField(max_length=32, validators=[my_validate])
        pub_time = serializers.DateField()
        # 3,序列化要走的字段
        category = serializers.CharField(source="get_category_display", read_only=True)
        publisher = PublisherSerializrs(read_only=True)
        authors = AuthorSerializer(many=True, read_only=True)  # 多对多要用many=True
        # 4,反序列化要走的字段
        # 反序列化提交的数据都是自定义的不是字段名(注意自定的数据这的字段名和提交数据一致,否则报错)
        post_category = serializers.IntegerField(write_only=True)
        publisher_id = serializers.IntegerField(write_only=True)
        author_list = serializers.ListField(write_only=True)
    
        # 1,提交数据的时候要重写create方法(增加的时候)
        def create(self, validated_data):
            # validated_data 校验通过的数据就是book_obj,通过ORM操作给Boook表增加数据
            print("在view中通过校验的数据:",validated_data)
            book_obj = Book.objects.create(
                title=validated_data["title"],
                pub_time=validated_data["pub_time"],
                category=validated_data["post_category"],
                publisher_id=validated_data["publisher_id"]
            )
            print("serializers中的book_obj", book_obj)
            # 需要把这个对象的多对多的数据创建出来
            book_obj.authors.add(*validated_data["author_list"])
            # 把值存在于ORM的操作更新到数据库中
            # book_obj.save()
            print(123)
            return book_obj
    
        # 2,更新数据的方法
        def update(self, instance, validated_data):
            # 参数说明:instance是要更新的book_obj对象, validated_data是通过校验的数据
            #  接下来就是ORM操作, 把要所有哦的字段都要写一遍
            instance.title = validated_data.get("title", instance.title)
            instance.pub_time = validated_data.get("pub_time", instance.pub_time)
            instance.category = validated_data.get("post_category", instance.category)
            instance.publisher_id = validated_data.get("publisher_id", instance.publisher_id)
            # 对于多对多的的外键需要判断存不存在author_list
            if validated_data.get("author_list"):
                # 用set设置的时候不用拍散,它会自动一个一个的去设置
                instance.authors.set(validated_data["author_list"])
            print(instance)
            # instance.save()
            print(456)
            return instance
    
        # 局部校验方法
        def validate_title(self, value):
            if "小雪" not in value.lower():
                raise serializers.ValidationError("不符合社会主义核心价值观")
            return value
    
        # 全局的校验方法
        def validate(self, attrs):
            if attrs["post_category"] == 1:
                return attrs
            else:
                raise serializers.ValidationError("1,难道不好吗?")
    
    正序,反序字段不统一

    小结:

    1. 先去cmd中下载rest_framework框架: pip install djangorestframework
    2. 在settings的app中注册rest_framework
    3. app里创建一个py文件导入rest_framework: from rest_framework import serializers
    4. 创建类继承serializers.Serializer
    5. 把表中的需要匹配的字段写在类中,注意many=True, 前端显示source="get_字段_display"
  • 相关阅读:
    Flask入门
    pippo主机管理
    K8S_v1.20+二进制安装(一)
    飞舞吧,少年
    paramiko封装
    Hippo登录展示功能
    mysql回档操作
    OpenSSH升级
    oracle存储过程 关于update的动态SQL工作心得
    关于博客的回忆
  • 原文地址:https://www.cnblogs.com/ljc-0923/p/10265338.html
Copyright © 2020-2023  润新知