drf 路由的写法和 actions 装饰器的使用

DRF 框架中 路由的写法

使用 drf 框架,在视图层中都是使用 CBV,基于类的视图函数。书写路由时需要调用 as_view

有三种写法:
1、没有继承ViewSetMixin的视图与路由对应关系

urlpatterns = [
    path('book/', views.BookAPIView.as_view()),
]

2、继承了ViewSetMixin的视图与路由对应关系

urlpatterns = [
    path('book4/', views.BookViewSet.as_view(actions={'get': 'list', 'post': 'create'})),
    path('book4/<int:pk>/', views.BookViewSetPk.as_view(actions={'get': 'retrieve', 'put': 'update', 'delete': 'delete'}))
]

3、自动生成第 2 种方法的两条路由,一条不带参数,一条附带整型参数

# 导入 routers 模块
from rest_framework.routers import DefaultRouter, SimpleRouter

# 实例化对象并注册路由
router = DefaultRouter()
router.register('book/', views.BookViewSet, 'book')

# 添加到路由列表中
urlpatterns = [
    path('admin/', admin.site.urls),
]
urlpatterns += router.urls

还有一种添加方式:使用路由分发

from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/', include(router.urls)),
]

DefaultRouterSimpleRouter 的区别

DefaultRouterSimpleRouter网址多一个根

DefaultRouter:

image

SimpleRouter:

image

action 装饰器的使用

由于视图层类继承了 VewSetMixin,该类重写了 as_view 方法,可以重定义五个接口所调用的方法,比如,我修改 get 请求方式调用的方法不再为ListModelMixin类中定义的 list方法,而是我在视图类中定义的 login 函数。

路由层:

urlpatterns = [
    path('book4/', views.BookViewSet.as_view(actions={'get': 'login', 'post': 'create'})),
]

视图层:

class BookViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Book.objects
    serializer_class = BookModelSerializer

    def login(self, request):
        print(request.method)
        return JsonResponse({'username': 'elijah'})

浏览器发起get请求返回login函数放回json格式字符串

image


但我们一般都会选择使用router模块自动生成路由,而自动生成的路由中 action 参数都是固定写了五个接口请求方法和其对应关系的,如果想指定某个请求方式会调用视图类中重写的函数,就得使用到 action装饰器。这样便可以生成一条该重写函数的专用api接口了

action 装饰器的参数:

  • methods=请求方法(列表)
  • detail=是否带id
  • url_path=地址如果不写,默认已方法名为地址
  • url_name=别名

写成如下,detail=True为真,会需要传入一个 pk 值,自动生成路由会生成一条路径:127.0.0.1:8080/book4/pk值/login ,getpost请求都会触发

from rest_framework.decorators import action

class BookViewSet(GenericViewSet, ListModelMixin, CreateModelMixin):
    queryset = Book.objects
    serializer_class = BookModelSerializer

    @action(methods=['GET', 'POST'], detail=True)
    def login(self, request, pk):
        print(request.method)
        return JsonResponse({'username': 'elijah'})

浏览器发起的 get请求:

image

detail=False为假,自动生成路由会生成一条路径:127.0.0.1:8080/book4/login

记得把 login 函数的 pk 形参去掉

class BookViewSet(ModelViewSet):
    queryset = Book.objects
    serializer_class = BookModelSerializer

    @action(methods=['GET', 'POST'], detail=False)
    def login(self, request):
        print(request.method)
        return JsonResponse({'username': 'elijah'})

image

通过action,怎么通过action判断,重写get_queryset,get_serializer_class

posted @ 2022-04-03 01:02  elijah_li  阅读(392)  评论(0编辑  收藏  举报
//一下两个链接最好自己保存下来,再上传到自己的博客园的“文件”选项中