12_05、路由组件

1、自动生成路由的源码分析

复制代码
# 只要继承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)# 跟之前一样了
复制代码

2、继承ModelViewSet的路由写法

复制代码
# 视图类,继承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 
复制代码

3、SimpleRouter和DefaultRouter

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

4、如果使用自动生成路由,必须继承谁及其子类?

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

5、action装饰器

复制代码
  # 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):

复制代码

6、路由的三种写法

复制代码
# 以后路由写法有三种
    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自动生成的路由更多
  
复制代码

7、补充:可以通过action判断,重写get_queryset,get_serializer_class

复制代码
class TestView2(GenericViewSet):

    queryset = Book.objects.all()
    serializer_class = BookSerializer

    def get_queryset(self):
        # 根据请求地址,返回的get_queryset不一样
        if self.action=='login':
            return Author.objects.all()
        else:
            return self.queryset

    def get_serializer_class(self):
        if self.action=='login':
            return AuthorSerialzier
        else:
            return BookSerializer
    @action(methods=['GET','POST'],detail=True)
    def login(self,request):
        obj=self.get_queryset()
        return Response("get-login")

    @action(methods=['GET'], detail=True)
    def test1(self,request):
        obj = self.get_queryset()
        return Response("get-test1")
复制代码

 

posted @   三三得九86  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示