• 三、几种视图实现源码剖析:django原生View、rest_framework.views.APIView、rest_framework.generics.GenericAPIView、ViewSetMixin


    一、django原生View:

      1、启动程序,预加载一条url,执行as_view(),返回view函数

    path('book/', views.BookView.as_view()),

      2、用户访问执行view方法,进入到dispatch:

     

       3、dispatch返回执行self.get的值,view调用的dispatch,视图类BookView调用的view,所以视图的返回值就是dispatch的返回值,dispatch的返回值就是view的返回值,即返回给页面的值。

    二:使用rest_framework.views.APIView的请求流程:

    re_path('^book/(d+)', views.BookDetailView.as_view()),

      1、APIView继承django的原生View,APIView下的as_view方法返回父类的as_view的返回值view

       2、用户访问执行view方法,进入到dispatch:APIView下实现了dispatch方法,所以优先执行APIView下的dispatch:

       3、dispatch的执行返回response,response等于视图的返回值。view调用的dispatch,视图类BookView调用的view,所以视图的返回值就是response,也就是dispatch的返回值,dispatch的返回值就是view的返回值,即返回给页面的值。

      

    三、 rest_framework.generics.GenericAPIView:它只是在APIView下进行了简单的封装,将原来实现视图的冗余代码封装在几个不同的类下

    path('author/', views.AuthorView.as_view()),
    class AuthorView(mixins.ListModelMixin, mixins.CreateModelMixin, generics.GenericAPIView):
        queryset = models.Author.objects.all()
        serializer_class = serializers.AuthorSerializers
    
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
        def post(self, request, *args, **kwargs):
            return self.create(request, *args, **kwargs)

      1、程序加载依次向父类查看as_view方法,mixins.ListModelMixin, mixins.CreateModelMixin下都没找到,generics.GenericAPIView下也没有,但它继承APIView,APIView下有,执行它,返回view。

       2、用户访问执行view,view的返回值就是dispatch的返回值,这时执行优先执行APIView下的dispatch,dispatch的返回值就是视图的返回值

       3、回到视图,视图的返回值时list方法的返回值,视图类没有实现list方法,依次向父类查找

       4、mixins.ListModelMixin拥有list方法,执行它,它返回序列化后的数据,也就是视图返回的数据,然后返回给dispatch,再到view。但是这过程是如何实现的呢,先看get_queryset方法

       5、get_queryset:在generics.GenericAPIView下找到了这个方法

     

      

      6、list调的get_queryset,视图调的list,所以self.queryset就是视图类下的queryset

       7、list方法将我们在视图中给到的queryset对象序列化后返回

    四、viewsets.ModelViewSet中的ViewSetMixin

     path('book/', views.BookView.as_view({'get': 'list', 'post': 'create'})),

      1、程序初识化执行as_view,它在ViewSetMixin下,不在是django原生View下的as_view,此时它接收一个action参数,即url地址中给的字典

      2、用户访问,执行view,此时"get","post"等字符串等于self.list和self.creater

       3、一步一步查dispatch,ViewSetMixin下没有实现,GenericAPIView也没有实现,GenericAPIView继承APIView,APIView实现了

     

     

       4、执行APIView下的dispatch,返回self.list的执行

       5、找self.list,发现它就是ListModelMixin类下的list方法

     

     总结:

      视图类继承django原生views.View时:as_view()返回view,它的返回值等于dispatch的返回值,dispatch的返回值等于视图类下get、post等方法的执行

      视图类继承rest_framework下的APIView时,as_view()依然执行的是原生View类下的as_view,但是APIView覆盖了dispatch方法,所以view的返回值是APIView下的dispatch执行。它重构了一个新的request

    由于使用上面两种方式实现视图时,冗余代码过多,mixins类能够精简代码:

      继承ListCreateAPIView和RetrieveUpdateDestroyAPIView类,只需要提供queryset对象与序列化类即可。as_view与dispatch的执行与APIView一致,只是最后一步视图中get、post等方法的执行被封装在mixins类中。

      viewsets.ModelViewSet类能够通过url实现所有请求方式只用一个CBV即可实现。主要是as_view的执行不再是原生View类下的as_view,而是ViewSetMixin下的as_view。它返回的view在用户访问执行时,url中的字典对应的执行方法在view方法经过对照处理,执行到dispatch时,他能够在mixins类中找到对应的执行类和方法,例如self.list、self.create

  • 相关阅读:
    hdu 4970 树状数组 “改段求段”
    hdu 2242 无向图/求用桥一分为二后使俩个bcc点权值和之差最小并输出 /缩点+2次新图dfs
    hdu3715 2-sat+二分
    hdu 3639 有向图缩点+建反向图+搜索
    hdu 3072 有向图缩点成最小树形图计算最小权
    hdu 3061 hdu 3996 最大权闭合图 最后一斩
    hdu 3879 hdu 3917 构造最大权闭合图 俩经典题
    hdu 4738 无向图缩点断桥 // 细节坑题
    hdu3452 无向树去掉最小的边集使任何叶子与根不连通 / 最小割
    hdu 3657 最小割的活用 / 奇偶方格取数类经典题 /最小割
  • 原文地址:https://www.cnblogs.com/aizhinong/p/12543799.html
Copyright © 2020-2023  润新知