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) return self.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