• 第十五篇 drf补充(序列化,视图)


    day07 drf常用api

    1.发布

    1.1 小程序

    • 选图片

    • 填内容

    • 提交

      {
      	cover:"https://mini-1251317460.cos.ap-chengdu.myqcloud.com/08a9daei1578736867828.png",
      	content:"小程序开发太简单了",
      	address:"北京市",
      	topic:1,
      	images:[
      		"https://mini-1251317460.cos.ap-chengdu.myqcloud.com/08a9daei1578736867828.png",
      		"https://mini-1251317460.cos.ap-chengdu.myqcloud.com/08a9daei1578736867828.png"
      	]
      }
      
      {
      	cover:"https://mini-1251317460.cos.ap-chengdu.myqcloud.com/08a9daei1578736867828.png",
      	content:"小程序开发太简单了",
      	address:"北京市",
      	topic:1,
      	
      	
      	
      	images:[
      		{
      			path:"https://mini-1251317460.cos.ap-chengdu.myqcloud.com/08a9daei1578736867828.png",
      			cos_key:"08a9daei1578736867828.pn"
      		},
      		{
      			path:"https://mini-1251317460.cos.ap-chengdu.myqcloud.com/08a9daei1578736867828.png",
      			cos_key:"08a9daei1578736867828.pn"
      		},
      	]
      }
      

    1.2 API

    from rest_framework.views import APIView
    from rest_framework.generics import CreateAPIView
    from rest_framework import serializers
    from apps.api import models
    class NewsDetailModelSerializer(serializers.Serializer):
        key = serializers.CharField()
        cos_path = serializers.CharField()
        
    class NewsModelSerializer(serializers.ModelSerializer):
        images = NewsDetailModelSerializer(many=True)
        class Meta:
            model = models.News
            fields = "__all__"
    
    class NewsView(CreateAPIView):
        """ 创建动态的API """
        serializer_class = NewsModelSerializer
    
    class News(models.Model):
        """
        动态
        """
        cover = models.CharField(verbose_name='封面', max_length=128)
        content = models.CharField(verbose_name='内容', max_length=255)
        topic = models.ForeignKey(verbose_name='话题', to='Topic', null=True, blank=True)
        address = models.CharField(verbose_name='位置', max_length=128, null=True, blank=True)
    
        user = models.ForeignKey(verbose_name='发布者', to='UserInfo', related_name='news')
    
        favor_count = models.PositiveIntegerField(verbose_name='赞数', default=0)
    
        viewer_count = models.PositiveIntegerField(verbose_name='浏览数', default=0)
    
        comment_count = models.PositiveIntegerField(verbose_name='评论数', default=0)
    
        create_date = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
    
    
    class NewsDetail(models.Model):
        """
        动态详细
        """
        key = models.CharField(verbose_name='腾讯对象存储中的文件名', max_length=128, help_text="用于以后在腾讯对象存储中删除")
        cos_path = models.CharField(verbose_name='腾讯对象存储中图片路径', max_length=128)
        news = models.ForeignKey(verbose_name='动态', to='News')
    

    1.3 规则

    {
        k1:v1,
        k2:v2,
        k3:{...},
        k4:[
            {....}
        ]
    }
    

    2.restful api回顾

    2.1 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)
    

    2.2 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)
        
        pagination_class = OldBoyLimitPagination # 分页
        filter_backends = [MinFilterBackend, MaxFilterBackend] #过滤条件
    

    2.2.0.0 RetrieveAPIView (处理单条记录)

    class NewsDetailModelSerializer(serializers.ModelSerializer):
        images = serializers.SerializerMethodField()
        create_date = serializers.DateTimeField(format="%Y-%m-%d %H:%M") # 时间格式化
    
        user = serializers.SerializerMethodField()
        topic = serializers.SerializerMethodField()
    
        viewer = serializers.SerializerMethodField()
        comment = serializers.SerializerMethodField()
    
        class Meta:
            model = models.News
            exclude = ['cover',]
    
        def get_images(self,obj):
            detail_queryset = models.NewsDetail.objects.filter(news=obj)
            # return [row.cos_path for row in detail_queryset]
            # return [{'id':row.id,'path':row.cos_path} for row in detail_queryset]
            return [model_to_dict(row,['id','cos_path']) for row in detail_queryset]
    
        def get_user(self, obj):
            return model_to_dict(obj.user, fields=['id', 'nickname', 'avatar'])
    
        def get_topic(self, obj):
            if not obj.topic:
                return
            return model_to_dict(obj.topic, fields=['id', 'title'])
    
        def get_viewer(self,obj):
            return 1
        def get_comment(self,obj):
            return 1
    
    class NewsDetailView(RetrieveAPIView):
        """
        获取单条数据---RetrieveAPIView
        """
        queryset = models.News.objects
        serializer_class = NewsDetailModelSerializer
    

    2.2.1 用户传递某些值

    创建用户时,自己在后台生成一个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()))
    
    

    2.2.2 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},
    ]
    

    2.2.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}
        ]
    

    2.3.4 复杂需求

    添加时用一个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
    

    2.3.5 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
    
    
    作者:华王 博客:https://www.cnblogs.com/huahuawang/
  • 相关阅读:
    jQuery
    jQuery
    jQuery
    jQuery
    jQuery
    JavaScript DOM 编程艺术
    JavaScript DOM 编程艺术
    JavaScript DOM 编程艺术
    【免费】Linux命令行与Shell脚本编程大全 第3版 PDF全本 21MB 百度网盘下载
    可重入函数(转载)
  • 原文地址:https://www.cnblogs.com/huahuawang/p/14816864.html
Copyright © 2020-2023  润新知