• restful api 回顾


    回顾一 APIView

    首先说一下序列化 serializers

    class UserModelSerializer(serializers.Serializer):
        key = serializers.CharField()
        cos_path = serializers.CharField()

    # 对于这样的序列化,我们有几个字段就写几个字段--只能序列化和表单验证 不能存数据库里
    class UserModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.UserInfo
            fields = "__all__"
    # 对于这样的序列化,可以通过serializer对象 点 save 保存到数据库里
    # 对于POST 请求
    from
    rest_framework.response import Response from rest_framework import serializers class UserModelSerializer(serializers.ModelSerializer): class Meta: model = models.UserInfo fields = "__all__" class UserView(APIView):def post(self,request,*args,**kwargs):
        # 序列化做校验 ser
    = UserModelSerializer(data=request.data) if ser.is_valid():
           # 存入数据库的两种形式 ser.save(添加额外的值)
    # models.UserInfo.objects.create(**ser.validated_data) ser.save(user_id=1) return Response(ser.data) return Response(ser.errors)
    # GET请求
    
    
    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()
         # 做校验 这里的user_list 是多条要用下面的形式 要是单条的 要写成 mang=False  局部更新的话 添加一个 partial=True
            ser = UserModelSerializer(instance=user_list,many=True)
            return Response(ser.data)

    回顾二 ListAPIView / CreateAPIView

    1. CreateAPIView

    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView):
        serializer_class = NewTestModelSerializer
    
    # 直接添加就完事了
    ---------------------------------------------------------------
    如果我们在添加前面干点事的话 重写post方法
    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewTestView(CreateAPIView):
        def post(self,request,*args,**kwargs):
        print(123)
        return super().post(self,request,*args,**kwargs)

    对于自己要多存一个值到数据库

    # 解释见下图
    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()))

    对于用于只展示几个字段的需求

    class NewTestModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.News
            fields = ["id","name","age"]

    2. ListAPIView 

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

    # 对于 ListAPIView 需要一个 查出来的数据 queryset

    补充一 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()

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

    两种方式  我分开写

    class NewTestModelSerializer(serializers.ModelSerializer):
    xx
    = serializers.CharField(source='id') class Meta: model = models.News fields = "__all__" # fields = ['id','name','age','gender','phone','xx',] class NewTestView(ListAPIView): serializer_class = NewTestModelSerializer queryset = models.User.objects.all()

    最后形式 [ {id:
    1,name:'xxx',age:18... xx:1}, {id:2,name:'xxx',age:11... xx:2}, {id:3,name:'xxx',age:99, xx:3}, ]

    方式二

    class NewTestModelSerializer(serializers.ModelSerializer):
        x1 = serializers.SerializerMethodField()
        class Meta:
            model = models.News
            fields = "__all__"
            # fields = ['id','name','age','gender','phone','x1']
    
        
        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... x1:1}, {id:2,name:'xxx',age:11... x1:2}, {id:3,name:'xxx',age:99, 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嵌套

    {
        "cover":"https://123.png",
        "content":"学习xuexi",
        "address":"北京",
        "topic":"1",
        "imageList":[
            
            {
                "key":"123.png",
                "cos_path":"https://12344"
            },
                    {
                "key":"123.png",
                "cos_path":"https://12344"
            }
            ]
    }

    我们有一段数据,下面的代码中  CreateNewsModelSerializer 校验了第一层数据  第二层的imageList数据没法校验 用 CreateNewsTopicModelSerializer 来校验

    class CreateNewsTopicModelSerializer(serializers.Serializer):
      """imageList的数据必须是这两个字段""" 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
     
  • 相关阅读:
    Mbps、Kbps、bps、kb、mb区别和换算
    Python导入模块方法
    C# WinForm 程序免安装 .NET Framework(XP/win7/win10环境运行)
    生成缩略图
    WCF 的优势和特点
    不要在using语句中调用WCF服务
    pb getchild获取DropDownDW子窗体后进行取值
    Bootstrap后台管理模板调研
    PB调用C#编写的DLL
    PowerBuilder与嵌入浏览器交互
  • 原文地址:https://www.cnblogs.com/a438842265/p/12459391.html
Copyright © 2020-2023  润新知