• Serializer


    API

    serializers.Serializer

    序列化

    read_only = True

    choice字段

      category = serializers.ChoiceField(
            choices=CHOICES, source='get_category_display')
    

    一对多 & 多对多

    先把其他序列化类(publisherserializer,authorserializer)写完

    通过有没有many = True来区分 一对多和多对多

       publisher = PublisherSerializer() # 一对多
       author = AuthorSerializer(many=True)  # 多对多
    
        def get(self, request):
            # book_obj = Book.objects.first()
            # serializer = BookSerilizer(book_obj)  ## 通过data区分是get 还是post
     
            book_list = Book.objects.all()
            serializer = BookSerilizer(book_list, many=True)  ## 通过data区分是get 还是post
            return Response(serializer.data) 
    

    反序列化

    write_only = True

    注意事项

    • 看源码

    • 分析前端传什么字段,区分不同的字段

    •     def post(self, request):
              book_obj = request.data
              serializer = BookSerilizer(data=book_obj) ## 通过data区分 是get还是post请求
              if serializer.is_valid():
                  serializer.save()
                  return Response(serializer.data)
              return Response(serializer.errors)
      
    • serializer 要重写 cerate方法 ==》 看源码 返回值

          def create(self, validated_data):
              book_obj = Book.objects.create(
                  title=validated_data['title'],
                  category=validated_data['s_category'],
                  pub_time=validated_data['pub_time'],
                  publisher_id=validated_data['s_publisher'])
              book_obj.author.add(*validated_data['s_author'])
              return book_obj
      

    serializers.ModelSerializer

    一对多 多对多 choice字段

    extra_kwargs
    
        def get_s_category(self,obj):
            return obj.get_category_display()     # choice
     
        def get_s_author(self, obj):                 # 多对对
            author_queryset = Author.objects.all()
            return [{"title": item.name} for item in author_queryset]
     
        def get_s_publisher(self, obj):     # 一对多
            return obj.publisher.title   
     
    

    校验

    validate_字段(self,value)

    #     def validate_title(self, value):
    #         if "python" not in value.lower():
    #             raise serializers.ValidationError("标题必须含有python")
    #         return value
    

    valudate(self,attrs)

    #     def validate(self, attrs):
    #         if attrs["w_category"] == 1 and attrs["publisher_id"] == 1:
    #             return attrs
    #         else:
    #             raise serializers.ValidationError("分类以及标题不符合要求")
    

    自定义函数校验

    def my_validate(value):
        if "敏感信息" in value.lower():
            raise serializers.ValidationError("不能含有敏感信息")
        else:
            return value
    

    回顾

    APIView ( 可以 )

    from rest_framework.response import Response
    class UserModelSerializer(serializers.ModelSerializer):
       class Meta:
           model = models.UserInfo
           fields = "__all__"
    
    class UserView(APIView):
    
       def get(self,request,*args,**kwargs):
           user_list = models.UserInfo.objects.all()
           ser = UserModelSerializer(instance=user_list,many=True)
           return Response(ser.data)
    
       def post(self,request,*args,**kwargs):
           ser = UserModelSerializer(data=request.data)
           if ser.is_valid():
               # models.UserInfo.objects.create(**ser.validated_data)
               ser.save(user_id=1)
               return Response(ser.data)
           return Response(ser.errors)
    

    ListAPIView

    ListAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView,DestroyAPIView
    
    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView,ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.News.objects.filter(id__gt=4)
    
    

    用户传一些值

    创建用户时,自己在后台生成一个UID。

    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView,ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.News.objects.filter(id__gt=4)
    
        def perform_create(self, serializer):
            serializer.save(uid=str(uuid.uuid4()))
    

    fields和exclude的区别?

    通过fields和exclude定制页面展示数据。

    需求:只显示用户表的id,name,age的数据,其他不显示。

    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            # fields = ["id","name",'age']
            # fields = "__all__"
            exclude = ['gender']
    
    class NewTestView(ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.User.objects.all()
        
    [
        {id:1,name:'xxx',age:18},
        {id:1,name:'xxx',age:11},
        {id:1,name:'xxx',age:99},
    ]
    

    需求:数据库有5个字段,显示7个字段。

    class NewTestModelSerializer(serializers.ModelSerializer):
        xx = serializers.CharField(source='id')
        x1 = serializers.SerializerMethodField()
        class Meta:
            model = models.News
            # fields = "__all__"
            # fields = ['id','name','age','gender','phone','xx','x1']
            exclude = ['id','name']
        
        def get_x1(self,obj):
            return obj.id
        
    class NewTestView(ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.User.objects.all()
        
    [
        {id:1,name:'xxx',age:18...   xx:1,x1:1},
        {id:2,name:'xxx',age:11...   xx:2,x1:2},
        {id:3,name:'xxx',age:99,     xx:3,x1:3},
    ]
    

    read_only

    添加时不要,查看时候需要。

    需求:编写两个接口 添加(3字段)、获取列表(5个字段)

    class NewTestModelSerializer(serializers.ModelSerializer):
        # phone = serializers.CharField(source='phone',read_only=True)
        # email = serializers.CharField(source='email',read_only=True)
        class Meta:
            model = models.News
            fields = "__all__"
            read_only_fields = ['phone','email',]
            
    class NewTestView(CreateAPIView, ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.User.objects.all()
        
    添加:
        {
            name:'xx',
            age:'19',
            gender:1
        }
    获取:
        [
            {name:'xx',age:'xx',gender:'',phone:'xx',email:xxx}
        ]
    

    复杂需求

    添加时用一个serializers、列表时用一个serializers

    class NewTestModelSerializer1(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
            
    class NewTestModelSerializer2(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView, ListAPIView):
        queryset = models.User.objects.all()
        
        def get_serializer_class(self):
            if self.request.method == 'POST':
                return NewTestModelSerializer1
            if self.request.method == 'GET':
                return NewTestModelSerializer2
    

    serializers嵌套

    class CreateNewsTopicModelSerializer(serializers.Serializer):
        key = serializers.CharField()
        cos_path = serializers.CharField()
    
    
    class CreateNewsModelSerializer(serializers.ModelSerializer):
        imageList = CreateNewsTopicModelSerializer(many=True)
    
        class Meta:
            model = models.News
            exclude = ['user', 'viewer_count', 'comment_count',"favor_count"]
    
        def create(self, validated_data):
            # 把imageList切走
            image_list = validated_data.pop('imageList')
    
            # 创建New表中的数据
            news_object = models.News.objects.create(**validated_data)
    
            data_list = models.NewsDetail.objects.bulk_create(
                [models.NewsDetail(**info, news=news_object) for info in image_list]
            )
            news_object.imageList = data_list
    
            if news_object.topic:
                news_object.topic.count += 1
                news_object.save()
    
            return news_object
    
    class NewsView(CreateAPIView):
        """
        发布动态
        """
        serializer_class = CreateNewsModelSerializer
        def perform_create(self, serializer):
            # 只能保存:News表中的数据()
            # 调用serializer对象的save(先调用create)
            new_object = serializer.save(user_id=1)
            return new_object
    
    

    Other

    手机号校验

    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    import re
    
    
    def phone_validator(value):
        if not re.match(r"^(1[3|4|5|6|7|8|9])d{9}$", value):
            raise ValidationError('手机格式错误')
    
    
    class MessageSerializer(serializers.Serializer):
        phone = serializers.CharField(label='手机号', validators=[phone_validator, ])
    
    

    serializer互相嵌套

    API

    serializers.Serializer

    序列化

    read_only = True

    choice字段

      category = serializers.ChoiceField(
            choices=CHOICES, source='get_category_display')
    

    一对多 & 多对多

    先把其他序列化类(publisherserializer,authorserializer)写完

    通过有没有many = True来区分 一对多和多对多

       publisher = PublisherSerializer() # 一对多
       author = AuthorSerializer(many=True)  # 多对多
    
        def get(self, request):
            # book_obj = Book.objects.first()
            # serializer = BookSerilizer(book_obj)  ## 通过data区分是get 还是post
     
            book_list = Book.objects.all()
            serializer = BookSerilizer(book_list, many=True)  ## 通过data区分是get 还是post
            return Response(serializer.data) 
    

    反序列化

    write_only = True

    注意事项

    • 看源码

    • 分析前端传什么字段,区分不同的字段

    •     def post(self, request):
              book_obj = request.data
              serializer = BookSerilizer(data=book_obj) ## 通过data区分 是get还是post请求
              if serializer.is_valid():
                  serializer.save()
                  return Response(serializer.data)
              return Response(serializer.errors)
      
    • serializer 要重写 cerate方法 ==》 看源码 返回值

          def create(self, validated_data):
              book_obj = Book.objects.create(
                  title=validated_data['title'],
                  category=validated_data['s_category'],
                  pub_time=validated_data['pub_time'],
                  publisher_id=validated_data['s_publisher'])
              book_obj.author.add(*validated_data['s_author'])
              return book_obj
      

    serializers.ModelSerializer

    一对多 多对多 choice字段

    extra_kwargs
    
        def get_s_category(self,obj):
            return obj.get_category_display()     # choice
     
        def get_s_author(self, obj):                 # 多对对
            author_queryset = Author.objects.all()
            return [{"title": item.name} for item in author_queryset]
     
        def get_s_publisher(self, obj):     # 一对多
            return obj.publisher.title   
     
    

    校验

    validate_字段(self,value)

    #     def validate_title(self, value):
    #         if "python" not in value.lower():
    #             raise serializers.ValidationError("标题必须含有python")
    #         return value
    

    valudate(self,attrs)

    #     def validate(self, attrs):
    #         if attrs["w_category"] == 1 and attrs["publisher_id"] == 1:
    #             return attrs
    #         else:
    #             raise serializers.ValidationError("分类以及标题不符合要求")
    

    自定义函数校验

    def my_validate(value):
        if "敏感信息" in value.lower():
            raise serializers.ValidationError("不能含有敏感信息")
        else:
            return value
    

    回顾

    APIView ( 可以 )

    from rest_framework.response import Response
    class UserModelSerializer(serializers.ModelSerializer):
       class Meta:
           model = models.UserInfo
           fields = "__all__"
    
    class UserView(APIView):
    
       def get(self,request,*args,**kwargs):
           user_list = models.UserInfo.objects.all()
           ser = UserModelSerializer(instance=user_list,many=True)
           return Response(ser.data)
    
       def post(self,request,*args,**kwargs):
           ser = UserModelSerializer(data=request.data)
           if ser.is_valid():
               # models.UserInfo.objects.create(**ser.validated_data)
               ser.save(user_id=1)
               return Response(ser.data)
           return Response(ser.errors)
    

    ListAPIView

    ListAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView,DestroyAPIView
    
    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView,ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.News.objects.filter(id__gt=4)
    
    

    用户传一些值

    创建用户时,自己在后台生成一个UID。

    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView,ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.News.objects.filter(id__gt=4)
    
        def perform_create(self, serializer):
            serializer.save(uid=str(uuid.uuid4()))
    

    fields和exclude的区别?

    通过fields和exclude定制页面展示数据。

    需求:只显示用户表的id,name,age的数据,其他不显示。

    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            # fields = ["id","name",'age']
            # fields = "__all__"
            exclude = ['gender']
    
    class NewTestView(ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.User.objects.all()
        
    [
        {id:1,name:'xxx',age:18},
        {id:1,name:'xxx',age:11},
        {id:1,name:'xxx',age:99},
    ]
    

    需求:数据库有5个字段,显示7个字段。

    class NewTestModelSerializer(serializers.ModelSerializer):
        xx = serializers.CharField(source='id')
        x1 = serializers.SerializerMethodField()
        class Meta:
            model = models.News
            # fields = "__all__"
            # fields = ['id','name','age','gender','phone','xx','x1']
            exclude = ['id','name']
        
        def get_x1(self,obj):
            return obj.id
        
    class NewTestView(ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.User.objects.all()
        
    [
        {id:1,name:'xxx',age:18...   xx:1,x1:1},
        {id:2,name:'xxx',age:11...   xx:2,x1:2},
        {id:3,name:'xxx',age:99,     xx:3,x1:3},
    ]
    

    read_only

    添加时不要,查看时候需要。

    需求:编写两个接口 添加(3字段)、获取列表(5个字段)

    class NewTestModelSerializer(serializers.ModelSerializer):
        # phone = serializers.CharField(source='phone',read_only=True)
        # email = serializers.CharField(source='email',read_only=True)
        class Meta:
            model = models.News
            fields = "__all__"
            read_only_fields = ['phone','email',]
            
    class NewTestView(CreateAPIView, ListAPIView):
        serializer_class = NewTestModelSerializer
        queryset = models.User.objects.all()
        
    添加:
        {
            name:'xx',
            age:'19',
            gender:1
        }
    获取:
        [
            {name:'xx',age:'xx',gender:'',phone:'xx',email:xxx}
        ]
    

    复杂需求

    添加时用一个serializers、列表时用一个serializers

    class NewTestModelSerializer1(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
            
    class NewTestModelSerializer2(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView, ListAPIView):
        queryset = models.User.objects.all()
        
        def get_serializer_class(self):
            if self.request.method == 'POST':
                return NewTestModelSerializer1
            if self.request.method == 'GET':
                return NewTestModelSerializer2
    

    serializers嵌套

    class CreateNewsTopicModelSerializer(serializers.Serializer):
        key = serializers.CharField()
        cos_path = serializers.CharField()
    
    
    class CreateNewsModelSerializer(serializers.ModelSerializer):
        imageList = CreateNewsTopicModelSerializer(many=True)
    
        class Meta:
            model = models.News
            exclude = ['user', 'viewer_count', 'comment_count',"favor_count"]
    
        def create(self, validated_data):
            # 把imageList切走
            image_list = validated_data.pop('imageList')
    
            # 创建New表中的数据
            news_object = models.News.objects.create(**validated_data)
    
            data_list = models.NewsDetail.objects.bulk_create(
                [models.NewsDetail(**info, news=news_object) for info in image_list]
            )
            news_object.imageList = data_list
    
            if news_object.topic:
                news_object.topic.count += 1
                news_object.save()
    
            return news_object
    
    class NewsView(CreateAPIView):
        """
        发布动态
        """
        serializer_class = CreateNewsModelSerializer
        def perform_create(self, serializer):
            # 只能保存:News表中的数据()
            # 调用serializer对象的save(先调用create)
            new_object = serializer.save(user_id=1)
            return new_object
    
    

    Other

    手机号校验

    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    import re
    
    
    def phone_validator(value):
        if not re.match(r"^(1[3|4|5|6|7|8|9])d{9}$", value):
            raise ValidationError('手机格式错误')
    
    
    class MessageSerializer(serializers.Serializer):
        phone = serializers.CharField(label='手机号', validators=[phone_validator, ])
    
    

    serializer互相嵌套

    images = NewsDetailModelSerializer(Many=True)  ==> images字段 [ {},{} ... ]
    
    
    images = NewsDetailModelSerializer(Many=True)  ==> images字段 [ {},{} ... ]
    
    
  • 相关阅读:
    Django部署到服务器
    springboot使用Redis缓存
    ubuntu下pip更换国内源
    ubuntu环境变量文件
    python open找不到路径
    centos 8 安装nginx
    centos8 mysql8的远程访问
    centos 8 安装mysql-server 8
    今日收获
    今日收获
  • 原文地址:https://www.cnblogs.com/tangshuo/p/12744438.html
Copyright © 2020-2023  润新知