路由器-Django REST框架
routers.py
路由器
资源路由允许您快速声明给定的足智多谋控制器的所有公共路由。而不是为你的索引声明单独的路线.一个足智多谋的路由在一行代码中声明它们。
— RubyonRails文档
有些Web框架(如Rails)提供了自动确定应用程序的URL应该如何映射到处理传入请求的逻辑的功能。
REST框架增加了对Django自动URL路由的支持,并为您提供了一种将视图逻辑连接到一组URL的简单、快速和一致的方法。
使用
下面是一个简单的URL conf示例,它使用Simple路由器
.
from rest_framework import routersrouter = 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‘sURL名称空间文档而include
API参考更多细节。
注:如果在超链接序列化程序中使用命名空间,则还需要确保view_name
序列化器上的参数正确地反映命名空间。在上面的例子中,您需要包含一个参数,例如view_name='app_name:user-detail'
对于序列化器字段,超链接到“用户详细信息”视图。
自动view_name
世代使用的模式如下%(model_name)-detail
...除非你的模特的名字真的冲突,否则你可能会过得更好。不使用超链接序列化器时,名称空间为Django REST Framework视图。
额外操作的路由选择
视点集标记用于路由的额外操作通过用@action
装饰师。这些额外的操作将包括在生成的路由中。例如,给定set_password
方法的UserViewSet
班级:
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import actionclass 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
装饰师。
例如,如果要将自定义操作的URL更改为^users/{pk}/change-password/$
,你可以写:
from myapp.permissions import IsAdminOrIsSelf
from rest_framework.decorators import actionclass 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指南
Simple路由器
此路由器包括标准的列单
, 创造
, 取回
, 更新
, 部分更新
和毁灭
行为。视图集还可以使用@action
装饰师。
| URL样式 | http方法 | 行动 | URL名称 |
| {前缀}/ | 到达 | 列单 | {basename}-列表 |
| 岗 | 创造 |
| {前缀}/{url_path}/ | 获取,或按“方法”参数指定的 | @action(Detail=false) | {basename}-{url_name} |
| {前缀}/{查找}/ | 到达 | 取回 | {basename}-细节 |
| 放 | 更新 |
| 补片 | 部分更新 |
| 删除 | 毁灭 |
| {前缀}/{查找}/{url_path}/ | 获取,或按“方法”参数指定的 | @action(Detail=True) | {basename}-{url_name} |
默认情况下,由Simple路由器
在后面加上一个斜杠。可以通过设置trailing_slash
争论False
当实例化路由器时。例如:
router = SimpleRouter(trailing_slash=False)
在Django中,尾随斜杠是传统的,但在其他一些框架(如Rails)中,默认情况下不使用。您选择使用哪种样式在很大程度上取决于您的偏好,尽管一些javascript框架可能希望使用特定的路由样式。
路由器将匹配包含除斜杠和句点字符以外的任何字符的查找值。对于更严格的(或宽松的)查找模式,请将lookup_value_regex
属性。例如,可以将查找限制为有效的UUID:
class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):lookup_field = 'my_model_id'lookup_value_regex = '[0-9a-f]{32}'
Default路由器
此路由器类似于Simple路由器
如前所述,但另外还包括一个默认的API根视图,该视图返回一个响应,其中包含指向所有列表视图的超链接。它还生成可选路由。.json
样式格式后缀。
| URL样式 | http方法 | 行动 | URL名称 |
| [.格式] | 到达 | 自动生成根视图 | API-根 |
| {前缀}/[.Format] | 到达 | 列单 | {basename}-列表 |
| 岗 | 创造 |
| {前缀}/{url_path}/[.Format] | 获取,或按“方法”参数指定的 | @action(Detail=false) | {basename}-{url_name} |
| {前缀}/{查找}/[.格式] | 到达 | 取回 | {basename}-细节 |
| 放 | 更新 |
| 补片 | 部分更新 |
| 删除 | 毁灭 |
| {前缀}/{查找}/{url_path}/[.Format] | 获取,或按“方法”参数指定的 | @action(Detail=True) | {basename}-{url_name} |
同.一样Simple路由器
可以通过设置trailing_slash
争论False
当实例化路由器时。
router = DefaultRouter(trailing_slash=False)
自定义路由器
实现自定义路由器并不是您经常需要做的事情,但是如果您对API的URL是如何构造的有特定的要求,那么它可能是有用的。这样做可以让您以可重用的方式封装URL结构,从而确保不必为每个新视图显式地编写URL模式。
实现自定义路由器的最简单方法是子类现有路由器类之一。这个.routes
属性用于模板将映射到每个视图集的URL模式。这个.routes
属性是Route
名叫元组。
的论点Route
命名元组是:
URL表示要路由的URL的字符串。可以包括下列格式字符串:
-
{prefix}
-用于这组路由的URL前缀。 -
{lookup}
-用于匹配单个实例的查找字段。 -
{trailing_slash}
-“/”或空字符串,取决于trailing_slash
争论。
映射:HTTP方法名称到视图方法的映射
名字,姓名*中使用的URL的名称function reverse() { [native code] }
打电话。可以包括以下格式字符串:
-
{basename}
-要用于创建的URL名称的基。
initkwargs*实例化视图时应传递的任何附加参数的字典。注意,detail
, basename
,和suffix
参数为视图集内省保留,也被可浏览的API用来生成视图名称和面包屑链接。
定制动态路由
您还可以自定义@action
装饰师被击溃了。包括DynamicRoute
中的命名元组。.routes
列表,设置detail
参数,适用于基于列表的路由和基于细节的路由。除了……之外detail
的论点DynamicRoute
是:
URL表示要路由的URL的字符串。可以包含与Route
,并另外接受{url_path}
格式字符串。
名字,姓名*中使用的URL的名称function reverse() { [native code] }
打电话。可以包括下列格式字符串:
-
{basename}
-要用于创建的URL名称的基。 -
{url_name}
--url_name
提供给@action
.
initkwargs*实例化视图时应传递的任何附加参数的字典。
例
下面的示例将仅路由到列单
和取回
操作,并且不使用尾斜杠约定。
from rest_framework.routers import Route, DynamicRoute, SimpleRouterclass 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 = UserSerializerlookup_field = 'username'@action(detail=True)def group_names(self, request, pk=None):"""Returns a list of all the group names that the givenuser 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
将生成以下映射..。
| URL | http方法 | 行动 | URL名称 |
| /用户 | 到达 | 列单 | 用户列表 |
| /user/{username} | 到达 | 取回 | 用户详细信息 |
| /user/{username}/group_name | 到达 | 组名 | 用户组名称 |
有关设置.routes
属性的源代码。Simple路由器
班级,等级。
高级定制路由器
如果您想提供完全自定义行为,则可以重写。BaseRouter
并覆盖get_urls(self)
方法。该方法应该检查已注册的视图集,并返回URL模式的列表。已注册的前缀、viewset和basename元组可以通过访问self.registry
属性。
您还可能希望覆盖get_default_basename(self, viewset)
方法,否则总是显式地设置basename
在向路由器注册视图集时使用。
第三方包
下面的第三方包也是可用的。
DRF嵌套路由器
这个DRF-嵌套路由器包提供用于处理嵌套资源的路由器和关系字段。
模型路由器(wq.db.rest)
这个wq.db包提供高级模型路由器类(和单例实例),扩展Default路由器
带着register_model()
API很像Django的admin.site.register
的唯一必要参数rest.router.register_model
是个模范课。url前缀、序列化程序和视图集的合理默认值将从模型和全局配置中推断出来。
from wq.db import rest
from myapp.models import MyModelrest.router.register_model(MyModel)
DRF-扩展
这个DRF-扩展
包装提供路由器为创造嵌套视图集, 集合级控制器带着可自定义端点名称.