在开发中咱们会设计好符合 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={}
)
]
复制代码