zoukankan      html  css  js  c++  java
  • 视图家族解析

    视图家族解析

    GenericAPIView 与 APIView 最为两大继承视图的区别:

     1)GenericViewSet和ViewSet都继承了ViewSetMixin,as_view都可以配置 请求-函数 映射
        
     2)GenericViewSet继承的是GenericAPIView视图类,用来完成标准的 model 类操作接口
    
     3)ViewSet继承的是APIView视图类,用来完成不需要 model 类参与,或是非标准的 model 类操作接口
        
          post请求在标准的 model 类操作下就是新增接口,登陆的post不满足
          post请求验证码的接口,不需要 model 类的参与
        
     案例:登陆的post请求,并不是完成数据的新增,只是用post提交数据,得到的结果也不是登陆的用户信息,而是登陆的认证信息
    

    删除操作:

    from rest_framework.viewsets import ModelViewSet
    class BookModelViewSet(ModelViewSet):
        queryset = models.Book.objects.filter(is_delete=False)
        serializer_class = serializers.BookModelSerializer
    
        # 删不是数据库,而是该记录中的删除字段
        def destroy(self, request, *args, **kwargs):
            instance = self.get_object()  # type: models.Book
            if not instance:
                return APIResponse(1, '删除失败')  # 实际操作,在此之前就做了判断
            instance.is_delete = True
            instance.save()
            return APIResponse(0, '删除成功')
    

    群删:

    destroy方法是完成is_delete字段值修改 - 重写destroy方法,自定义实现体
        def destroy(self, request, *args, **kwargs):
            car_obj = self.get_object()
            car_obj.is_delete = True
            car_obj.save()
            return APIResponse(msg='删除成功')
    
    

    群增:

        群增与单增必须公用一个接口,都要走create方法 - 重写create方法,用逻辑进行拆分
    
    class CarModelViewSet(ModelViewSet):
        queryset = models.Car.objects.filter(is_delete=False).all()
        serializer_class = serializers.CarModelSerializer
       
        def create(self, request, *args, **kwargs):
                request_data = request.data
                if isinstance(request_data, list):
                    car_ser = self.get_serializer(data=request_data, many=True)
                    car_ser.is_valid(raise_exception=True)
                    car_obj = car_ser.save()
                    return APIResponse(msg='群增成功', results=self.get_serializer(car_obj, many=True).data)
    
                return super().create(request, *args, **kwargs) 
    

    路由添加子列表方式:

    from django.conf.urls import include
    from rest_framework.routers import SimpleRouter
    router = SimpleRouter()
    
    # 所有路由与ViewSet视图类的都可以注册,会产生 '^v6/books/$' 和 '^v6/books/(?P<pk>[^/.]+)/$'
    router.register('v6/books', views.BookModelViewSet)
    
    urlpatterns = [
        # 第一种添加子列表方式
        url(r'^', include(router.urls)),
    ]
    	#第二种添加子列表方式
    urlpatterns.extend(router.urls)
    

    为响应信息添加状态码:

    响应的结果只有数据,没有数据状态码和状态信息 ???
    
    让群查有状态码和状态信息 - 重写list方法
        def list(self, request, *args, **kwargs):
            response = super().list(request, *args, **kwargs)
            return APIResponse(results=response.data)
    
    
    

    mixins视图工具类:

    from rest_framework.mixins import RetrieveModelMixin, ListModelMixin, CreateModelMixin
    
    class CarReadCreateGenericAPIView(ListModelMixin, RetrieveModelMixin, CreateModelMixin, GenericAPIView):
        
        queryset = models.Car.objects.filter(is_delete=False).all()
        serializer_class = serializers.CarModelSerializer
        lookup_url_kwarg = 'pk'
        
         # 单查
    
        def get(self, request, *args, **kwargs):
            # car_obj = self.get_object()
            # car_ser = self.get_serializer(car_obj)
            # return APIResponse(results=car_ser.data)
            response = self.retrieve(request, *args, **kwargs)
            return APIResponse(results=response.data)
    
    
        # 单增
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)
    

    Generics工具视图类:

    # 单独完成群查接口
    from rest_framework.generics import ListAPIView
    class CarListAPIView(ListAPIView):
        queryset = models.Car.objects.filter(is_delete=False).all()
        serializer_class = serializers.CarModelSerializer
    
    
    # 单查(get)、单整体改(put)、单局部改(patch)、单删接口(delete)
    from rest_framework.generics import RetrieveUpdateDestroyAPIView
    class CarRetrieveUpdateDestroyAPIView(RetrieveUpdateDestroyAPIView):
        queryset = models.Car.objects.filter(is_delete=False).all()
        serializer_class = serializers.CarModelSerializer
    

    推演过程:

    class CarView(APIView):        # 初始版(全手撸)
        def get(self):
            obj,
            ser,
            response,
            
    class CarView(GenericAPIView):  # 不会出现,中间产物
        queryset,
        serializer_class,
        lookup_url_kwarg,
        def get(self):
            obj,
            ser,
            response,
    
    class CarView(RetrieveModelMixin, GenericAPIView):  # 自定义组合,可以超过九种
        queryset,
        serializer_class,
        lookup_url_kwarg,
        def get(self):
            self.retrieve()
            
    class CarView(RetrieveAPIView):  # 最终产物,系统只提供了九种组合,RetrieveAPIView是其中一种
        queryset,
        serializer_class,
        lookup_url_kwarg,
    
    GenericAPIView
    1)继承APIView,所以拥有APIView的所有
    2)get_queryset方法,配置queryset类属性,提供视图类相关的Models
    3)在第二条基础上,get_object方法,配置lookup_url_kwarg类属性,提供视图类相关的具体Model
    4)get_serializer方法,配置serializer_class类属性,提供视图类相关的序列化对象
    
    总结:GenericAPIView就是在APIView基础上额外提供了三个方法,三个类属性,如果不配合视图工具类,体现不出优势
    目的:视图中的增删改查逻辑相似,但操作的资源不一致,操作资源就是操作 资源对象们、资源对象以及资源相关的序列化类,
    将这三者形成配置,那操作逻辑就一致,就可以进行封装
    
    3、mixins视图工具类们:五个类,六个方法
    1)要配合GenericAPIView类使用,将单查、群查、单增,单整体改,单局部改,单删六个接口
    封装成retrieve、list、create、update、partial_update、destroy六个方法
    原因:六个方法的实现体,调用的方法就是GenericAPIView提供的,所以要配合GenericAPIView类使用
    
    4、generics工具视图类们:九种组合
    1)帮我们将不同个数不同种类的mixins与GenericAPIView进行组合
    2)不同的组合帮我们实现好对应的get、post、put、patch、delete方法
    3)需要我们自己配置三个类属性即可:queryset、serializer_class、lookup_url_kwarg
    

    视图集总结

    
        核心:视图集都继承了 ViewSetMixin类,该类重写了as_view方法,相比APIView的as_view方法,额外多出了一个参数actions
        
        as_view({'get': 'list'}) 传入的{'get': 'list'}就被actions介绍,原理是将get请求映射给视图类的list函数进行处理
    
    1)为什么有GenericViewSet和ViewSet两个视图集基类
        GenericViewSet(ViewSetMixin, GenericAPIView),该分支严格满足资源接口
        
        ViewSet(ViewSetMixin, APIView),该分支满足的接口与资源Model类关系不是特别密切:登录接口、短信验证码接口
    
    2)ReadOnlyModelViewSet,ModelViewSet两个视图集子类,就是做个一堆mixin与GenericViewSet相结合,
    
       自己在urls文件中配置as_view设置映射关系
    
  • 相关阅读:
    java中Annotation注解的定义与使用
    ABC184 D——F && 一道LC好题
    YZYのPython 作业~
    杂谈(11.13——lca && mst)
    树状数组(BIT)—— 一篇就够了
    Codeforces Round #673 (Div. 2)[A-E]
    Codeforces Round #674 (Div. 3)
    Educational Codeforces Round 95 (Rated for Div. 2) [A -- E]
    LEETCODE 第 205 场周赛
    Codeforces Round #662 (Div. 2)
  • 原文地址:https://www.cnblogs.com/shaozheng/p/12121379.html
Copyright © 2011-2022 走看看