在開發中咱們會設計好符合 Restful 風格的 API, 那框架已經幫咱們提供了這些快捷方式。html
在咱們定義好了 MedusaBlogViewSet
的狀況下, 咱們註冊 URL 的時候僅須要:python
#!/usr/bin/env python
# _*_ Coding: UTF-8 _*_
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'medusa/blog', MedusaBlogViewSet)
urlpatterns = router.urls
複製代碼
register()
有兩個強制性的參數:django
prefix
:用於這組路由的 URL 前綴字符串, 用於路由匹配viewset
:你定義的視圖集若是你的視圖集實現了獲取列表/獲取詳情/新增/刪除/修改的方法, 那你定義路由將會解析成這樣:api
URL 格式 | 請求方法 | 請求說明 | 視圖集方法 |
---|---|---|---|
^medusa/blog$ |
GET |
獲取列表 | list() |
^medusa/blog/{pk}$ |
GET |
獲取詳情 | retrieve() |
^medusa/blog$ |
POST |
新增 | create() |
^medusa/blog/{pk}$ |
PUT |
更新 | update() |
^medusa/blog/{pk}$ |
DELETE |
刪除 | destroy() |
在你的視圖集沒有指定 queryset
屬性或者自定義了 get_queryset()
方法的時候, 你可能會看到這樣一條錯誤信息:app
'basename' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.
複製代碼
因此你須要指定一個可選參數:basename
, 默認狀況下你不須要手動指定它的值, 它是建立 URL 名稱的基礎屬性, 通常是用你指定的 queryset
屬性值自動設置的。框架
默認狀況下路由都須要添加 /
做爲路由結尾, 你也能夠修改該規則, 只須要修改參數 trailing_slash=False
便可:函數
router = SimpleRouter(trailing_slash=False)
複製代碼
該路由器生成 URL 的方式: post
在上面的例子中, 咱們使用了 urlpatterns = router.urls
的方式註冊了路由對象, 咱們一般會使用 include
進行路由註冊, 在 Django 中可能有一些咱們自定義的視圖, 不須要使用 SimpleRouter
進行註冊:url
#!/usr/bin/env python
# _*_ Coding: UTF-8 _*_
from django.conf.urls import url
from django.urls import include
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'medusa/blog', MedusaBlogViewSet)
urlpatterns = [
..., # 其餘路由配置
url(r'^', include(router.urls)),
]
複製代碼
例如你的項目安排上, 安排關於用戶模塊是在配置的界面, 那麼你的路由多是這樣的:spa
/api/v1.0/configure/user
複製代碼
那我對用戶的配置可能有如下幾個方法處理:
GET
:獲取用戶詳情/列表PUT
:修改用戶信息POST
:新增用戶信息DELETE
:刪除用戶信息問題來了, 若是我不想建立一個新的關於用戶的視圖類, 可是我又想增長一個修改密碼的 API 接口怎麼辦? 若是你從事過其餘產品 API 調度工做的時候, 你可能會浮現這樣類型的接口:
/api/v1.0/configure/user/1/reset
複製代碼
很規範的接口方式, 那你在你的 ViewSet 裏怎麼體現呢?
#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
class UserViewSet(ModelViewSet):
...
@action(methods=['post'], detail=True)
def reset(self, request, pk=None):
...
複製代碼
是的, 使用 action
裝飾器裝飾, 並指定參數便可, 默認狀況下你生成的 URL 是根據你的函數名稱生成了, 你也能夠經過 url_name
和 url_path
制定路由的後綴名稱, 也能夠經過 permission_classes
來制定用戶訪問權限。
這個路由器和 SimpleRouter
很相似, 但會包含一個默認的 API 根視圖, 返回一個包含全部列表視圖的超連接響應數據。 固然, 該路由的路徑也會使用 /
結尾, 你能夠用 trailing_slash=False
來棄用該規則:
router = DefaultRouter(trailing_slash=False)
複製代碼
該路由生成 URL 的方式:
其實在開發中這不是你使用路由器的最好方式, 可是在你須要自定義 URL 格式的時候使用這個方式將會變得頗有效, 而實現自定義路由是將現有路由做爲子類之一, 其 .routes
屬性是 Route
的命名元組的列表數據, 功能是用於模板化將映射到每一個視圖集的 URL 模式。 Route
命名元祖的參數有:
url
:表明須要路由的 URL 字符串, 你可能須要這樣字符串
"{prefix}"
:用於這組路由器的前綴字符串"{lookup}"
:用於單個實例匹配的字符串, 如ID"{trailing_slash}"
:根據 trailing_slash
參數制定結尾字符mapping
:HTTP 方法名稱到視圖方法的映射name
:reverse
呼叫用使用的 URL 名稱,你可能須要這樣的字符串
"{basename}"
:用於建立 URL 名稱的基礎字符initkwargs
:實例化視圖須要的參數字典其實以上文字內容是官方文檔的描述內容加上我本身的理解裝飾了一下, 可是看到這幾行字的描述信息, 確實是不知道它的功能到底怎麼樣定義, 恰好看到某位大佬的博客, 參考並實踐了一下:
附參考的博客地址:www.cnblogs.com/liubiao/p/6…
在使用 @action
的時候你也能夠自定義路由方式, .routes
的列表是包含 DynamicRoute
命名的元組, 將 detail
參數設置爲適用於基於列表的路由和基於詳細信息的路由, DynamicRoute
除了 detail
參數:
url
:一個表明路由 URL 的字符串, 可能會包含和 Route
相同格式的字符串, 並接受一個 "{url_path}"
格式的字符串name
:reverse
呼叫中使用的 URL 名稱, 你可能須要如下格式的字符串:
"{basename}"
:用於建立 URL 的名稱基礎"{url_name}"
:提供給 @action
的 url_name
initkwargs
:實例化試圖須要的參數字典#!/usr/bin/env python
# _*_ coding: UTF-8 _*_
from rest_framework.routers import Route, DynamicRoute, SimpleRouter
class CustomReadOnlyRouter(SimpleRouter):
""" A router for read-only APIs, which doesn't use trailing slashes. """
routes = [
Route(
url=r'^{prefix}$',
mapping={'get': 'list'},
name='{basename}-list',
detail=False,
initkwargs={'suffix': 'List'}
),
Route(
url=r'^{prefix}/{lookup}$',
mapping={'get': 'retrieve'},
name='{basename}-detail',
detail=True,
initkwargs={'suffix': 'Detail'}
),
DynamicRoute(
url=r'^{prefix}/{lookup}/{url_path}$',
name='{basename}-{url_name}',
detail=True,
initkwargs={}
)
]
複製代碼