drf : 自动生成路由,视图层自定义方法,路由映射方法,action参数。

扩展一个知识点: 在Django中,代码只要顶格编写,程序一运行,代码将直接执行。

drf路由Routers

自动生成路由需要继承ViewSetMixin子类,重写了as_view()方法。

导入模块:

from rest_framework import routers

创建router对象,并注册视图集合,例如:

router = SimpleRouter()
router.register('books', views.BookAPIView)

参数解析:

register(prefix, viewset, basename=None)

# prefix -该视图集的路由前缀
# viewset -视图集
# basename -路由别名的前缀,默认为None,可以不传,不能重复。

上述代码会形成的路由如下:

[
<URLPattern '^books/$' [name='books-list']>, 
<URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>
]

添加路由数据具有两种方式:

第一种写路由的模式:

url.py

urlpatterns = [
    # 将请求映射到对应的方法
    path('books/', views.BookAPIView.as_view({'get':'list'})),
    path('books/<int:pk>', views.BookAPIView.as_view({'get':'retrieve'})),
]

urlpatterns += router.urls

第二种书写路由的模式:

url.py

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

此时客户端发送请求: http://127.0.0.1:8000/api/books/

Views.py,两种数据添加方式视图层书写方式一致。

from rest_framework.viewsets import ModelViewSet

# 五个接口
class BookAPIView(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

路由router形成URL的方式

路由之DefaultRouter()

导入模块:

from rest_framework.routers import DefaultRouter

url.py

router = DefaultRouter()
router.register('books', views.BookAPIView)
"""
[
<URLPattern '^books/$' [name='books-list']>, 
<URLPattern '^books\.(?P<format>[a-z0-9]+)/?$' [name='books-list']>, 
<URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>, 
<URLPattern '^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='books-detail']>, 
<URLPattern '^$' [name='api-root']>, <URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>
]
"""
print(router.urls)

urlpatterns = [
    path('',include(router.urls))
]

views.py

from rest_framework.viewsets import ModelViewSet

# 五个接口
class BookAPIView(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

此时访问: http://127.0.0.1:8000/,为根路由

路由之SimpleRouter()

导入模块:

from rest_framework.routers import SimpleRouter

url.py

from rest_framework.routers import SimpleRouter,DefaultRouter
from django.urls import path,include


router = SimpleRouter()
router.register('books', views.BookAPIView)
"""
[
<URLPattern '^books/$' [name='books-list']>, 
<URLPattern '^books/(?P<pk>[^/.]+)/$' [name='books-detail']>
]
"""
print(router.urls)

views.py

from rest_framework.viewsets import ModelViewSet

# 五个接口
class BookAPIView(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BookSerializers

不会产生根路由。

DefaultRouter与SimpleRouter的区别是:

DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。

视图层自定义方法,路由映射方法。

第一种模式,手动编写路由。

url.py

from rest_framework.routers import SimpleRouter
from django.urls import path,include


router = SimpleRouter()
router.register('books', views.BookAPIView)


urlpatterns = [
    path('books/',views.BookAPIView.as_view({'get':'login'})),
    path('',include(router.urls))
]

views.py

class BookAPIView(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BookSerializers


    def login(self, request, *args, **kwargs):
        # 客户端发送的GET请求
        # print(request)
        return Response("查询成功")

第二种模式,自动路由如何自定义方法之装饰器action。

导入模块:

from rest_framework.decorators import action

url.py

from rest_framework.routers import SimpleRouter,DefaultRouter
from django.urls import path,include


router = SimpleRouter()
router.register('books', views.BookAPIView)


urlpatterns = [
    path('',include(router.urls))
]

views.py

from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet, GenericViewSet, ViewSet
from rest_framework.decorators import action

# 五个接口
class BookAPIView(ModelViewSet):
    queryset = Books.objects.all()
    serializer_class = BookSerializers


    @action(methods=['GET'],detail=False,url_path='login')
    def login(self, request, *args, **kwargs):
        return Response(request.data)

action参数:

  • methods: 声明该action对应的请求方式,列表传递
  • detail: 声明该action路径是否为单一资源对应(False查询所有数据接口,True查询单条数据接口)
@action(methods=['GET'], detail=False, url_path='login')
def login(self, request, *args, **kwargs):
  print(kwargs) #{'pk':1}
  return Response(request.data)


# detail=False
^books/login/$
# detail=True
^books/(?P<pk>[^/.]+)/login/$

action同样也需要视图层继承ViewSetMixin

总结:

# 自动生成路由的视图类
-需要继承ViewSetMixin+9个视图子类
-需要继承ViewSetMixin+视图类(APIView,GenericAPIView)+5个视图扩展类
# 可以使用action的视图类
ViewSetMixin+视图类
posted @ 2022-04-11 15:19  谢俊杰  阅读(358)  评论(0编辑  收藏  举报