DRF之路由元件
繼承ViewSetMixin類,路由寫法
只要繼承ViewSetMixin 及其子類,路由寫法就變了
檢視類:繼承ViewSetMixin,路由寫法變了--->而且檢視類中的方法不一定寫成get,post..,可以隨意命名,只不過定義路由時寫法變成了path('test/', views.TestView.as_view({'get': 'login'})),get請求執行login方法
如何實現
注意:class TestView(ViewSetMixin,APIView)中 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) returnself.dispatch(request, *args, **kwargs)# 跟之前一樣了
檢視類繼承ModelViewSet路由寫法
class PublishView(ModelViewSet): # 修改路由,5個介面 queryset = Publish.objects.all() serializer_class = PublishSerializers
路由
path('publish/', views.PublishView.as_view({'get': 'list', 'post': 'create'})), path('publish/<int:pk>', views.PublishView.as_view({'get': 'retrieve', 'post': '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)) # 第一種(推薦)需要先匯入include模組 urlpatterns+=router.urls # 第二種
使用自動生成路由,必須繼承誰及其子類?
GenericViewSet+5個檢視擴充套件類至少之一---》才能自動生成
SimpleRouter和DefaultRouter
SimpleRouter和DefaultRouter 用法完全一樣,只是生成的路由不一樣DefaultRouter比SimpleRouter多一條根地址,一般咱麼就用SimpleRouter就可以
DefaultRouter
from django.urls import path, include from app01 import views from rest_framework.routers import SimpleRouter,DefaultRouter # router = SimpleRouter() router = DefaultRouter() router.register('publish', views.PublishView, 'publish') urlpatterns = [ path('admin/', admin.site.urls), # path('publish/', views.PublishView.as_view()), # path('publish/<int:pk>', views.PublishDataView.as_view()), path('books/', views.BookView.as_view()), path('books/<int:pk>', views.BookDataView.as_view()), path('api/v1/', include(router.urls)), # 前面可以加相加的東西 例如 'api/v1/' path('test', views.TestView.as_view({'get': 'login'})), # get請求來了,執行檢視類中的login方法 # path('publish/', views.PublishView.as_view({'get': 'list', 'post': 'create'})), # path('publish/<int:pk>', views.PublishView.as_view({'get': 'retrieve', 'post': 'update', 'delete': 'destroy'})), ]
SimpleRouter
from django.urls import path, include from app01 import views from rest_framework.routers import SimpleRouter,DefaultRouter router = SimpleRouter() # router = DefaultRouter() router.register('publish', views.PublishView, 'publish') urlpatterns = [ path('admin/', admin.site.urls), # path('publish/', views.PublishView.as_view()), # path('publish/<int:pk>', views.PublishDataView.as_view()), path('books/', views.BookView.as_view()), path('books/<int:pk>', views.BookDataView.as_view()), path('api/v1/', include(router.urls)), # 前面可以加相加的東西 例如 'api/v1/' path('test', views.TestView.as_view({'get': 'login'})), # get請求來了,執行檢視類中的login方法 # path('publish/', views.PublishView.as_view({'get': 'list', 'post': 'create'})), # path('publish/<int:pk>', views.PublishView.as_view({'get': 'retrieve', 'post': 'update', 'delete': 'destroy'})), ]
action裝飾器
# action裝飾器可以再生成路由 from rest_framework.decorators import action
action裝飾器引數介紹
methods=請求方式,列表
detail=是否帶id
url_path=地址,如果不寫預設以方法名為地址
url_name別名
只要是繼承ViewSetMixin檢視類中方法,都可以加action裝飾器,只要加了,自動生成路由會多生成--》127.0.0.1:8080/test/login
from rest_framework.decorators import action class TestView(ViewSetMixin, APIView): # ViewSetMixin必須寫在前面 @action(methods=['GET', 'POST'], detail=False) def login(self, request): return Response('get請求')
路由
from django.urls import path, include from app01 import views from rest_framework.routers import SimpleRouter,DefaultRouter router = SimpleRouter() router.register('test', views.TestView, 'test') urlpatterns = [ path('admin/', admin.site.urls), path('', include(router.urls)), # 前面可以加相加的東西 例如 'api/v1/' ]
detail=True
# 生成的路徑是127.0.0.1:8080/test/數字/login @action(methods=['GET','POST'],detail=True) def login(self,request):
url_path
# 生成的路徑是127.0.0.1:8080/test/xxx:get或post都能觸發 @action(methods=['GET','POST'],detail=False,url_path='xxx') def login(self,request):
可以通過action判斷,重寫get_queryset,get_serializer_class