路由器
资源路由可以让你快速声明所有给定的足智多谋的控制器的共同路线。相反,宣布独立的路线索引的......一个足智多谋的路线宣称他们在一个单一的代码行。
一些Web框架如Rails的用于自动地确定如何为应用程序的URL应该被映射到所述逻辑提供功能与处理传入请求的交易。
REST框架增加了对自动URL路由Django的支持,并为您提供您的接线鉴于逻辑URL集的简单,快速,一致的方式。
用法
这里有一个简单的URL的conf的例子,使用SimpleRouter
。
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = router.urls
有两个强制参数的register()
方法:
prefix
- URL前缀用于此路由集合。viewset
- 该视图集类。
另外,您还可以指定一个额外的参数:
basename
-该基地用于所创建的URL名称。如果未设置基本名称将根据自动生成queryset
的视图集的属性,如果它有一个。请注意,如果视图集不包括queryset
属性,则必须将basename
注册视图集时。
上面的例子将产生下面的URL模式:
- URL模式:
^users/$
名称:'user-list'
- URL模式:
^users/{pk}/$
名称:'user-detail'
- URL模式:
^accounts/$
名称:'account-list'
- URL模式:
^accounts/{pk}/$
名称:'account-detail'
注意:该basename
参数用于指定视图名称模式的起始部分。在上面的例子,这就是user
或account
部分。
通常你不会需要到指定basename
的说法,但如果你有,你已经定义了一个自定义的一个视图集get_queryset
方法,那么视图集可能没有一个.queryset
属性集。如果试图注册该视图集中你会看到这样的错误:
'basename' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.
这意味着你需要明确地设置basename
注册视图集的时候,因为它不能自动从型号名称确定的说法。
使用include
与路由器
在.urls
上一个路由器实例属性是一个简单的URL模式的标准列表。有你如何能包括这些URL许多不同的风格。
例如,您可以附加router.urls
到现有视图的列表...
router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
]
urlpatterns += router.urls
另外,您可以使用Django的include
功能,这样的...
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^', include(router.urls)),
]
您可以使用include
一个应用程序的命名空间:
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include((router.urls, 'app_name'))),
]
或两者的应用程序和实例命名空间:
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include((router.urls, 'app_name'), namespace='instance_name')),
]
见Django的URL命名空间文档和include
API参考的更多细节。
注意:如果使用带您还需要确保任何超链接串行命名空间view_name
上的串行参数正确反映命名空间。在上面的例子中你需要包括参数,如 view_name='app_name:user-detail'
用于超链接到用户细节视图串行字段。
自动view_name
生成使用像的图案%(model_name)-detail
。除非你的模型名称冲突实际上你可能会更好不使用超链接的串行时命名空间Django的REST框架意见。
路由额外行动
一个视图集可用于路由标记额外的操作通过装饰用的方法@action
装饰。这些额外的措施将包括在生成的路线。例如,给定的set_password
上所述方法UserViewSet
类:
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import action
class UserViewSet(ModelViewSet):
...
@action(methods=['post'], detail=True, permission_classes=[IsAdminOrIsSelf])
def set_password(self, request, pk=None):
...
下面的路由将产生:
- URL模式:
^users/{pk}/set_password/$
- 网址名称:
'user-set-password'
默认情况下,URL模式是基于方法名和URL名称是的组合ViewSet.basename
和复姓方法名。如果你不想使用默认设置这些值,可以代替提供url_path
和url_name
参数的@action
装饰。
例如,如果你想改变我们的自定义操作的网址^users/{pk}/change-password/$
,你可以写:
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import action
class UserViewSet(ModelViewSet):
...
@action(methods=['post'], detail=True, permission_classes=[IsAdminOrIsSelf],
url_path='change-password', url_name='change_password')
def set_password(self, request, pk=None):
...
上面的例子,现在会生成以下URL模式:
- URL路径:
^users/{pk}/change-password/$
- 网址名称:
'user-change_password'
API指南
SimpleRouter
该路由器包括一套标准的途径list
,create
,retrieve
,update
,partial_update
和destroy
行动。该视图集中还可以标记其他方法来进行路由,使用@action
装饰。
URL风格 | HTTP方法 | 行动 | URL名称 |
---|---|---|---|
{字首}/ | 得到 | 名单 | {}基本名-list |
POST | 创建 | ||
{前缀} / {url_path} / | GET,或由methods 参数指定 |
@Action(详细=假) 装饰方法 |
{}基名 - {} URL_NAME |
{前缀} / {查找} / | 得到 | 取回 | {}基本名-detail |
放 | 更新 | ||
补丁 | partial_update | ||
删除 | 破坏 | ||
{前缀} / {查找} / {url_path} / | GET,或由methods 参数指定 |
@Action(详细=真) 装饰方法 |
{}基名 - {} URL_NAME |
默认情况下,通过建立的网址SimpleRouter
被附加以斜杠。这种行为可以通过设置来修改trailing_slash
参数来False
实例化路由器时。例如:
router = SimpleRouter(trailing_slash=False)
结尾的斜杠在Django常规的,但在某些其他框架如导轨不使用缺省值。您选用的风格在很大程度上是偏好的问题,但也有一些JavaScript框架可以期待一个特定的路由风格。
路由器将匹配查找含有除斜线和周期字符的任何字符的值。对于更严格的(或宽松)查找图案,设置lookup_value_regex
在机视图集属性。例如,你可以限制查找到有效的UUID:
class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
lookup_field = 'my_model_id'
lookup_value_regex = '[0-9a-f]{32}'
defaultrouter中
该路由器为类似于SimpleRouter
如上述,但另外还包括一个默认API根视图,即返回包含超链接到所有的列表视图的响应。它还为可选路线.json
风格的格式后缀。
URL风格 | HTTP方法 | 行动 | URL名称 |
---|---|---|---|
[。格式] | 得到 | 自动生成的根查看 | 火根 |
{前缀} / [格式] | 得到 | 名单 | {}基本名-list |
POST | 创建 | ||
{前缀} / {url_path} / [格式] | GET,或由methods 参数指定 |
@Action(详细=假) 装饰方法 |
{}基名 - {} URL_NAME |
{前缀} / {查找} / [格式] | 得到 | 取回 | {}基本名-detail |
放 | 更新 | ||
补丁 | partial_update | ||
删除 | 破坏 | ||
{前缀} / {查找} / {url_path} / [格式] | GET,或由methods 参数指定 |
@Action(详细=真) 装饰方法 |
{}基名 - {} URL_NAME |
正如SimpleRouter
在URL路径后斜线可以通过设置除去trailing_slash
参数False
实例路由器时。
router = DefaultRouter(trailing_slash=False)
定制路由器
实现自定义路由器是不是你需要经常做的,但如果你有关于如何为你的API的网址是结构化的具体要求也可以是有用的。这样做可以让你封装URL结构,确保你没有明确地写你的URL模式为每个新视图可重复使用的方式。
实现自定义路由器最简单的方法是继承现有的路由器类之一。该.routes
属性用于模板将被映射到每个视图集的URL的模式。该.routes
属性是一个列表Route
命名的元组。
到的参数Route
命名为元组是:
URL被路由代表URL的字符串。可以包括以下格式的字符串:
{prefix}
- URL前缀用于此路由集合。{lookup}
- 查找字段用于匹配的单个实例。{trailing_slash}
-无论是“/”或空字符串,这取决于trailing_slash
参数。
映射:HTTP方法名的映射到视图的方法
名称:URL的名称中使用reverse
电话。可以包括以下格式的字符串:
{basename}
- 该基地用于所创建的URL名称。
initkwargs:的应实例视图时被传递任何额外的参数的字典。请注意,detail
,basename
,和suffix
参数保留给视图集中内省和也使用可浏览的API生成视图名称和面包屑链接。
自定义动态路由
您还可以自定义如何@action
装饰路由。包括DynamicRoute
在指定的元组.routes
列表,设置detail
参数为适用于基于明细清单为基础和路线。此外detail
,该参数DynamicRoute
是:
URL被路由代表URL的字符串。可包括相同的格式字符串作为Route
,另外接受{url_path}
格式字符串。
名称:URL的名称中使用reverse
电话。可以包括以下格式的字符串:
{basename}
- 该基地用于所创建的URL名称。{url_name}
-在url_name
所提供的@action
。
initkwargs:的应实例视图时被传递任何额外的参数的字典。
例
下面的例子将只对路线list
和retrieve
行动,并且不使用尾部斜杠约定。
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={}
)
]
让我们来看看我们的路线CustomReadOnlyRouter
会产生一个简单的视图集。
views.py
:
class UserViewSet(viewsets.ReadOnlyModelViewSet):
"""
A viewset that provides the standard actions
"""
queryset = User.objects.all()
serializer_class = UserSerializer
lookup_field = 'username'
@action(detail=True)
def group_names(self, request, pk=None):
"""
Returns a list of all the group names that the given
user belongs to.
"""
user = self.get_object()
groups = user.groups.all()
return Response([group.name for group in groups])
urls.py
:
router = CustomReadOnlyRouter()
router.register('users', UserViewSet)
urlpatterns = router.urls
下面的映射将产生...
网址 | HTTP方法 | 行动 | URL名称 |
---|---|---|---|
/用户 | 得到 | 名单 | 用户列表 |
/用户/ {用户名} | 得到 | 取回 | 用户细节 |
/用户/ {名} / GROUP_NAMES | 得到 | GROUP_NAMES | 用户组名 |
用于设置的其他例子.routes
的属性,请参阅所述的源代码SimpleRouter
的类。
高级定制路由器
如果你想提供完全定制的行为,则可以覆盖BaseRouter
和重写get_urls(self)
方法。该方法应检查注册viewsets和返回的URL模式列表。注册的前缀,视图集和基本名称元组可以通过访问进行检查self.registry
属性。
您可能还需要重写get_default_basename(self, viewset)
方法,否则始终明确设置basename
与路由器注册您的viewsets时的说法。
第三方软件包
下面的第三方软件包也可提供。
DRF嵌套路由器
的DRF-嵌套的路由器包提供路由器和关系字段用于与嵌套资源工作。
型号路由器(wq.db.rest)
所述wq.db包提供了一个先进ModelRouter延伸类(和单个实例)DefaultRouter
用register_model()
的API。就像Django的admin.site.register
,唯一需要的参数rest.router.register_model
是一个模型类。一个URL前缀,串行和视图集中合理的默认值会从模型和全局配置中推断出来。
from wq.db import rest
from myapp.models import MyModel
rest.router.register_model(MyModel)