内容介绍
在开发中设计中符合 Restful 风格的 API。
SimpleRouter
使用已经定义好的 ModelNameViewSet 注册 URL
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'apps/modelname', ModelNameViewSet)
urlpatterns = router.urls
register() 有两个强制性的参数:
- prefix:用于这组路由的 URL 前缀字符串,用于路由匹配
- viewset:定义的视图集
视图集实现了获取列表/获取详情/新增/删除/修改的方法, 定义路由将会解析成
URL | 格式请求 | 方法请求 | 说明视图集方法 |
---|---|---|---|
^medusa/blog$ | GET | 获取列表 | list() |
^medusa/blog/{pk}$ | GET | 获取详情 | retrieve() |
^medusa/blog$ | POST | 新增 | create() |
^medusa/blog/{pk}$ | PUT | 更新 | update() |
^medusa/blog/{pk}$ | DELETE | 删除 | destroy() |
默认情况下路由都需要添加 / 作为路由结尾,你也可以修改该规则,只需要修改参数 trailing_slash=False
router = SimpleRouter(trailing_slash=False)
该路由器生成 URL 的方式:
URL Style | HTTP Method | Action | URL Name |
---|---|---|---|
{prefix}/ | GET | list | {basename}-list |
POST | create | ||
{prefix}/{url_path}/ | GET, or as specified by `methods` argument | `@action(detail=False)` decorated method | {basename}-{url_name} |
{prefix}/{lookup}/ | GET | retrieve | {basename}-detail |
PUT | update | ||
PATCH | partial_update | ||
DELETE | destroy | ||
{prefix}/{lookup}/{url_path}/ | GET, or as specified by `methods` argument | `@action(detail=True)` decorated method | {basename}-{url_name} |
include
使用 urlpatterns = router.urls 的方式注册路由对象通常会使用 include 进行路由注册, 在 Django 中自定义的视图不需要使用 SimpleRouter 进行注册。
from django.conf.urls import url
from django.urls import include
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'apps/modelname', ModelNameViewSet)
urlpatterns = [
..., # 其他路由配置
url(r'^', include(router.urls)),
]
路由绑定其他操作
对用户的配置可能有以下几个方法处理:
- GET:获取用户详情/列表
- PUT:修改用户信息
- POST:新增用户信息
- DLETE:删除用户信息
规范的接口方式ViewSet, action 装饰器装饰,并指定参数即可, 默认情况下你生成的 URL 是根据你的函数名称生成了,你也可以通过 url_name 和 url_path 制定路由的后缀名称,,也可以通过 permission_classes 来制定用户访问权限。
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):
...
DefaultRouter
这个路由器和 SimpleRouter 很类似,但会包含一个默认的 API 根视图,返回一个包含所有列表视图的超链接响应数据。 当然,该路由的路径也会使用 / 结尾,你可以用 trailing_slash=False 来弃用该规则。
router = DefaultRouter(trailing_slash=False)
URL Style | HTTP Method | Action | URL Name |
---|---|---|---|
[.format] | GET | automatically generated root view | api-root |
{prefix}/[.format] | GET | list | {basename}-list |
POST | create | ||
{prefix}/{url_path}/[.format] | GET, or as specified by `methods` argument | `@action(detail=False)` decorated method | {basename}-{url_name} |
{prefix}/{lookup}/[.format] | GET | retrieve | {basename}-detail |
PUT | update | ||
PATCH | partial_update | ||
DELETE | destroy | ||
{prefix}/{lookup}/{url_path}/[.format] | GET, or as specified by `methods` argument | `@action(detail=True)` decorated method | {basename}-{url_name} |
自定义路由器(不常用)
需要自定义 URL 格式的时候使用,而实现自定义路由是将现有路由作为子类之一,其 .routes 属性是 Route 的命名元组的列表数据,功能是用于模板化将映射到每个视图集的 URL 模式。
Route 命名元祖的参数
- url:代表需要路由的 URL 字符串, 你可能需要这样字符串
“{prefix}”:用于这组路由器的前缀字符串
“{lookup}”:用于单个实例匹配的字符串, 如ID
“{trailing_slash}”:根据 trailing_slash 参数制定结尾字符 - mapping:HTTP 方法名称到视图方法的映射
- name:reverse 呼叫用使用的 URL 名称,你可能需要这样的字符串
“{basename}”:用于创建 URL 名称的基础字符 - initkwargs:实例化视图需要的参数字典
自定义解析路线
在使用 @action 的时候你也可以自定义路由方式,.routes 的列表是包含 DynamicRoute 命名的元组,将 detail 参数设置为适用于基于列表的路由和基于详细信息的路由,DynamicRoute 除了 detail 参数:
- url:一个代表路由 URL 的字符串, 可能会包含和 Route 相同格式的字符串, 并接受一个 “{url_path}” 格式的字符串
- name:reverse 呼叫中使用的 URL 名称, 你可能需要以下格式的字符串:
“{basename}”:用于创建 URL 的名称基础
“{url_name}”:提供给 @action 的 url_name - initkwargs:实例化试图需要的参数字典
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={
}
)
]