drf 视图组件和路由组件

内容详细

1 视图组件

        # 9个视图子类---》是视图类
            -CreateAPIView, ListAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView
        ListCreateAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, \
            RetrieveDestroyAPIView


        # 视图集
        # ViewSet=APIView+ViewSetMixin
        # GenericViewSet=GenericAPIView+ViewSetMixin
        # 以后只要想自动生成路由,必须继承ViewSetMixin及其子类
        # 之前的写法可以沿用,只是如果要自动生成路由可以选择继承ViewSet,GenericViewSet

        from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
        from rest_framework.viewsets import ViewSet,GenericViewSet
        from rest_framework.viewsets import ViewSetMixin
        # 第四层:通过9个视图子类,编写视图函数
        # from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView
        # from rest_framework.generics import ListCreateAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, \
        #     RetrieveDestroyAPIView
        #
        #
        # # class PublishView(ListCreateAPIView):  # 查询所有和新增接口就有了
        # # class PublishView(CreateAPIView):  # 新增接口就有了
        # class PublishView(ListAPIView):  # 查询所有接口就有了
        #     queryset = Publish.objects.all()
        #     serializer_class = PublishSerialzier
        #
        #     # 有可能要重写--》get_queryset--》get_serializer_class--》perform_create--》get,post方法
        #
        #
        # class PublishDetailView(RetrieveUpdateDestroyAPIView): # 查询单条,删除,修改
        # # class PublishDetailView(RetrieveAPIView): # 查询单条
        # # class PublishDetailView(DestroyAPIView): # 删除
        # # class PublishDetailView(UpdateAPIView): # 修改
        # # class PublishDetailView(RetrieveDestroyAPIView): # 查询单条和删除
        # # class PublishDetailView(RetrieveUpdateAPIView): # 查询单条和更新
        # # class PublishDetailView(UpdateAPIView,DestroyAPIView): # 更新和删除
        #     queryset = Publish.objects.all()
        #     serializer_class = PublishSerialzier



        # 第五层:通过ViewSet写视图类

        # 5个接口,都用一个视图类----》路由 有两个get
        from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
        # ViewSet=APIView+ViewSetMixin
        # GenericViewSet=GenericAPIView+ViewSetMixin
        # 以后只要想自动生成路由,必须继承ViewSetMixin及其子类
        # 之前的写法可以沿用,只是如果要自动生成路由可以选择继承ViewSet,GenericViewSet
        from rest_framework.viewsets import ViewSet,GenericViewSet
        from rest_framework.viewsets import ViewSetMixin

        # 集成了5个视图扩展类+GenericViewSet(ViewSetMixin, generics.GenericAPIView)
        # ViewSetMixin-->控制了路由写法变了
        # class PublishView(ModelViewSet):  # 修改路由,5个接口
        class PublishView(ReadOnlyModelViewSet):  # 修改路由,只读,查所有,查单个
            queryset = Publish.objects.all()
            serializer_class = PublishSerialzier

2 路由组件

        # 只要继承ViewSetMixin 及其子类,路由写法就变了
        # 视图类:继承ViewSetMixin,路由写法变了--->而且视图类中的方法不一定写成get,post..,可以随意命名,只不过定义路由时写法变成了path('test/', views.TestView.as_view({'get': 'login'})),get请求执行login方法

        # 到底如何执行的?
            # ViewSetMixin必须写在前面
            ViewSetMixin--》as_view--->类的查找顺序---》actions就是传入的字典---》view闭包函数
          def view(request, *args, **kwargs):
             #    get      login
                for method, action in actions.items():
                # 把login方法的内存地址给了handler
                handler = getattr(self, action)
                # 通过反射,设置给get---》对应login---》get请求执行get方法,现在get方法变成了login方法
                setattr(self, method, handler)
              return self.dispatch(request, *args, **kwargs)# 跟之前一样了


        # 视图类,继承ModelViewSet,路由写法
            path('publish/', views.PublishView.as_view({'get':'list','post':'create'})),
            path('publish/<int:pk>', views.PublishView.as_view({'get':'retrieve','put':'update','delete':'destroy'}))

            # 到现在,咱们有了一种方式,可以在一个视图类中写很多方法,通过路由的配置,实现一个视图函数对应很多路由

            # 上面的两个路由,可以自动生成--->生成上面那两条地址
                第一步:导入drf提供的路由类
              from rest_framework.routers import SimpleRouter
                    第二步:实例化得到对象
                    router = SimpleRouter()
              第三步:注册路由
                    router.register('地址', 视图类, '别名')
              router.register('publish', views.PublishView, 'publish')
              第四步:在urlpatterns加入(两种方式)
                path('/api/v1', include(router.urls))
                urlpatterns+=router.urls 


           # SimpleRouter和DefaultRouter 用法完全一样,只是生成的路由不一样DefaultRouter比SimpleRouter多一条根地址,一般咱么就用SimpleRouter就可以



          # 如果使用自动生成路由,必须继承谁及其子类?
            GenericViewSet+5个视图扩展类至少之一---》才能自动生成
            ModelViewSet
            ReadOnlyModelViewSet


          # action装饰器
            -只要是继承ViewSetMixin视图类中方法,都可以加action装饰器,只要加了,自动生成路由会多生成--》127.0.0.1:8080/test/login:get或post都能触发
            @action(methods=['GET','POST'],detail=False)
            def login(self,request):

           # 如果写法如下,生成的路径是127.0.0.1:8080/test/数字/login
            @action(methods=['GET','POST'],detail=True)
            def login(self,request):
        # 以后路由写法有三种
            path('books/<int:pk>', views.BookDetailView.as_view()),
          # 继承了ViewSetMixin
          path('publish/', views.PublishView.as_view({'get':'list','post':'create'}))
          # 自动生成路由
          from rest_framework.routers import SimpleRouter,DefaultRouter
          router = SimpleRouter()
          router.register('publish', views.PublishView, 'publish')
            # 路由注册,两种方式
          path('api/v1/', include(router.urls)),
          urlpatterns+=router.urls
          # 路由类,有连个SimpleRouter,DefaultRouter,DefaultRouter自动生成的路由更多

          # action装饰器---》只要继承ViewSetMixin都能自动生成路由
            # methods=请求方法,列表,
            # detail=是否带id,
            # url_path=地址如果不写,默认已方法名为地址,
            # url_name=别名
            # 写成如下,自动生成路由会生成一条路径:127.0.0.1:8080/test/login -->get,post都会触发
            @action(methods=['GET','POST'],detail=True)
            def login(self,request):

           # 如果写法如下,生成的路径是127.0.0.1:8080/test/数字/login
            @action(methods=['GET','POST'],detail=True)
            def login(self,request):

         # 通过action,怎么通过action判断,重写get_queryset,get_serializer_class
posted @ 2022-05-22 22:09  风花雪月*  阅读(19)  评论(0编辑  收藏  举报