视图组件(继承不同类重写视图类第四层和第五层)、路由组件(修改路由的全部写法)

今日内容概要

  • 视图组件
  • 路由组件
内容详细 1、视图组件
# 9个视图子类--是视图类 from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView, ListCreateAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView

第四层: 通过9个视图子类,重写视图函数 views.py:
# 第四层:通过9个视图子类,重写视图函数 # 9个视图子类 from rest_framework.generics import CreateAPIView, ListAPIView, DestroyAPIView, RetrieveAPIView, UpdateAPIView from rest_framework.generics import ListCreateAPIView, RetrieveUpdateAPIView, RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIViewclass PublishView(ListCreateAPIView):# 查询所有和新增接口就有了 # class PublishView(CreateAPIView):# 新增接口就有了 # class PublishView(ListAPIView):# 查询所有接口就有了 queryset = Publish.objects.all() serializer_class = PublishSerialzierclass 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# 但是页有可能要重写--》get_queryset--》get_serializer_class--》perform_create--》get,post等方法

视图组件(继承不同类重写视图类第四层和第五层)、路由组件(修改路由的全部写法)
文章图片

第五层: 通过ViewSet,重写视图函数 views.py:
# 第五层:通过ViewSet写视图类 # 5个接口,都用一个视图类----》导致了路由问题:有两个get from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet""" from rest_framework.viewsets import ViewSet, GenericViewSet from rest_framework.viewsets import ViewSetMixin ViewSet=APIView+ViewSetMixin GenericViewSet=GenericAPIView+ViewSetMixin以后只要想自动生成路由,必须继承ViewSetMixin及其子类 之前的写法可以沿用,只是如果要自动生成路由可以选择继承ViewSet 或者 GenericViewSet """ class PublishView(ModelViewSet):# 修改路由,5个接口都有 # 继承了5个视图扩展类+GenericViewSet(ViewSetMixin, generics.GenericAPIView) # 其中 ViewSetMixin-->控制了路由写法变了# class PublishView(ReadOnlyModelViewSet):# 修改路由,只有 查所有,查单个两个接口 queryset = Publish.objects.all() serializer_class = PublishSerialzier##### 在urls.py中配置 加入方式一: from rest_framework.routers import SimpleRouterrouter = SimpleRouter() router.register('publish', views.PublishView, 'publish') # 然后要把路由加入到urlpatterns的列表中 两种方式urlpatterns = [ path('admin/', admin.site.urls),path('books/', views.BookView.as_view()), path('books/', views.BookView.as_view()), ]# 加入方式一 # router.urls他会自动生成列表 包含两种地址: publishs / publishs/ # print(router.urls)# [, ] urlpatterns += router.urls# 两个列表相加##### 在urls.py中配置 加入方式二: from django.urls import include from rest_framework.routers import SimpleRouterrouter = SimpleRouter() router.register('publish', views.PublishView, 'publish') # 然后要把路由加入到urlpatterns的列表中 两种方式urlpatterns = [ path('admin/', admin.site.urls),path('books/', views.BookView.as_view()), path('books/', views.BookView.as_view()),# 加入方式二: path('api/v1/', include(router.urls)),# from django.urls import include # 这样写等用于下面两句''引号中可以随意加入前缀# 但是默认就有: publishs / publishs/ # path('api/v1/publishs/', views.PublishView.as_view()), # # path('api/v1/publishs/', views.PublishDetailView.as_view()), ]

视图组件(继承不同类重写视图类第四层和第五层)、路由组件(修改路由的全部写法)
文章图片

2、路由组件
# 只要继承ViewSetMixin 及其子类,路由写法就变了# 视图类只要继承ViewSetMixin,路由写法就变了 而且视图类中的方法不一定写成get,post.. 可以随意命名 路由改为: path('login/', views.TestView.as_view({'get': 'login'})),# 意思为:get请求来了,执行视图类中的login方法# 如何执行的?源码分析 ViewSetMixin必须写在前面 as_view--->类的查找顺序 actions就是传入的字典---》view闭包函数: def view(request, *args, **kwargs): #getlogin 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)# 跟之前一样了

演示继承 ViewSetMixin类 的路由写法:
### views.py中:from rest_framework.viewsets import ViewSetMixin, ViewSet, GenericViewSet from rest_framework.views import APIView from rest_framework.decorators import actionclass TestView(ViewSetMixin, APIView):# ViewSetMixin必须写在前面 # class TestView(ViewSet):# 等同于上面 class TestView(ViewSetMixin, APIView) # class TestView(ViewSetMixin, GenericAPIView):# 只要继承ViewSetMixin的 该类就必须写在前面 def login(self, request): return Response("get-login")# 路由中 urls.py: # 路由组件: path('login/', views.TestView.as_view({'get': 'login'})),# 意思为:get请求来了,执行视图类中的login方法

视图组件(继承不同类重写视图类第四层和第五层)、路由组件(修改路由的全部写法)
文章图片

继承ModelViewSet 类,路由写法:
# views.py:# 路由组件 class PublishView(ModelViewSet):# 修改路由,5个接口都有 queryset = Publish.objects.all() serializer_class = PublishSerialzier# urls.py:path('publish/', views.PublishView.as_view({'get': 'list', 'post': 'create'})), path('publish/', 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个视图扩展类至少之一 才能自动生成# action装饰器 # action装饰器可以再生成路由 记得要修改路由为自动生成模式 from rest_framework.decorators import action class TestView(ViewSetMixin, APIView):# ViewSetMixin必须写在前面 # action的默认参数: # methods=请求方法,列表,detail=是否带id,url_path=地址如果不写,默认已方法名为地址,url_name=别名 # 写成如下,自动生成路由会生成一条路由:127.0.0.1:8080/test/login -->get,post都会触发 @action(methods=['GET', 'POST'], detail=False) def login(self, request): return Response("get-login")# 如果写法如下,生成的路径是127.0.0.1:8080/test/数字/login @action(methods=['GET', 'POST'], detail=True) def login(self, request):# 使用action,怎么通过action判断? 重写 get_queryset、get_serializer_class class TestView2(GenericViewSet): queryset = Book.objects.all() serializer_class = BookSerializerdef get_queryset(self): # 根据请求地址,返回的get_queryset不一样 if self.action=='login': return Author.objects.all() else: return self.querysetdef 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")

【视图组件(继承不同类重写视图类第四层和第五层)、路由组件(修改路由的全部写法)】视图组件(继承不同类重写视图类第四层和第五层)、路由组件(修改路由的全部写法)
文章图片

    推荐阅读