当前位置: 代码迷 >> 综合 >> Routers - Django REST framework
  详细解决方案

Routers - Django REST framework

热度:54   发布时间:2023-09-14 11:14:28.0

路由器-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参数用于指定视图名称模式的初始部分。在上面的示例中,这是useraccount部分。

通常你不会需要若要指定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名称空间文档而includeAPI参考更多细节。


:如果在超链接序列化程序中使用命名空间,则还需要确保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_pathurl_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-扩展包装提供路由器为创造嵌套视图集, 集合级控制器带着可自定义端点名称.

  相关解决方案