1. 程式人生 > 其它 >drf路由元件(4星)

drf路由元件(4星)

目錄

路由元件(4星)

路由Routers

對於檢視集ViewSet, 我們除了可以自己手動指明請求方式與動作action之間的對應關係外,還可以使用Routers來幫助我們快速實現路由資訊。

REST framework提供了兩個router

  • SimpleRouter(推薦)
  • DefaultRouter

DefaultRouter與SimpleRouter的區別是,DefaultRouter會多附帶一個預設的API根檢視,返回一個包含所有列表檢視的超連結響應資料。下面就是DefaultRouter的效果。

使用方法

建立router物件,並註冊檢視集,例如

from rest_framework.routers import DefaultRouter, SimpleRouter
router = DefaultRouter()
router.register('book', views.BookAPIView, basename='book')

register(prefix, viewset, basename)

  • prefix 該檢視集的路由字首
  • viewset 檢視集(不用加as_view())
  • basename 路由別名的字首

如上述程式碼會形成的路由如下:

^books/$    name: book-list
^books/{pk}/$   name: book-detail

新增路由資料

可以有兩種方式(推薦第一種)

urlpatterns = [
    ...
    url(r'^', include(router.urls))
]

urlpatterns = [
    ...
]
urlpatterns += router.urls

程式碼演示

使用路由類給檢視集生成了路由地址

### 檢視類必須繼承了ViewSetMixin的子類才能使用自動生成路由
from rest_framework.viewsets import ModelViewSet

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

    def login(self, request):
        return Response('登陸')

路由程式碼:

"""使用drf提供路由類router給檢視集生成路由列表"""
# 例項化路由類
# drf提供一共提供了兩個路由類給我們使用,他們用法一致,功能幾乎一樣
from rest_framework.routers import DefaultRouter, SimpleRouter # 隨便用一個
router = DefaultRouter()
# 註冊檢視集
# router.register("路由字首",檢視集類) 別名basename可以省略
router.register('book', views.BookAPIView, basename='book')
# 把生成的路由列表追加到urlpatterns
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(router.urls))
]
或
urlpatterns += router.urls

上面的程式碼就成功生成了路由地址(增刪改查一個/查多個), 但是不會新增我們在檢視集自定義方法的路由。

所以我們如果也要給自定義方法生成路由,則需要進行action動作的宣告。

重寫方法

重寫list方法

在檢視類中

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

    def list(self, request, *args, **kwargs):
        # 呼叫父類的方法(不然直接呼叫self.list()就遞迴了)
        response = super().list(request, *args, **kwargs)
        # 這裡的response.data是之前返回給前端的資料
        res = {'result': response.data, 'msg': '查詢成功', 'code': 100}
        return Response(res)

在路由中

from rest_framework.routers import SimpleRouter

router = SimpleRouter()
router.register('book', views.BookAPIView, basename='book')

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

擴充套件自己的方法(action裝飾器)

在檢視集中,如果想要讓Router自動幫助我們為自定義的動作生成路由資訊,需要使用rest_framework.decorators.action裝飾器。

以action裝飾器裝飾的方法名會作為action動作名,與list、retrieve等同。

action裝飾器可以接收兩個引數:

  • methods: 宣告該action對應的請求方式,列表傳遞

  • detail: 宣告該action的路徑是否與單一資源對應

    • True 表示路徑格式是xxx//action方法名/
    • False 表示路徑格式是xxx/action方法名/
    from rest_framework.viewsets import ModelViewSet
    from rest_framework.decorators import action
    class TestAPIView(ModelViewSet):
        queryset = Book.objects.all()
        serializer_class = BookModelSerializer
    	# methods 設定當前方法允許哪些http請求訪問當前檢視方法
        # detail 設定當前檢視方法是否是操作一個數據
        # detail為True,表示路徑名格式應該為 ^book/(?P<pk>[^/.]+)/login/$
        # 在**kwargs裡可以取到pk的值
        @action(methods=['GET', ], detail=False)
        def login(self, request, *args, **kwargs):
            return Response('登陸')
    

    在urls.py中

    from rest_framework.routers import SimpleRouter
    router = SimpleRouter()
    router.register('test', views.TestAPIView, 'test')
    urlpatterns = [
        path('', include(router.urls)),
    ]
    
    • url_path: 把指定資料新增到路徑字尾,預設是把函式名新增到路徑字尾

      url_path = 'xxx' 那麼url為 test/(?P [ ^/. ]+)/xxx/$

    • url_name='xxx' 起別名

    補充(瞭解),必須繼承ViewSetMixin的檢視類才有

    檢視類有action屬性,是當此請求要執行的函式名

總結

1 自動生成路由的檢視類,
	-需要繼承ViewSetMixin+9個檢視字類
    -需要繼承ViewSetMixin+檢視類(GenericAPIView。。。)+5個檢視擴充套件類
2 可以使用action的檢視類,ViewSetMixin+檢視類(APIView...)