Django 路由(SimpleRouter, DefaultRouter,ExtendedDefaultRouter)

django 路由

SimpleRouter

1
2
3
4
5
from rest_framework.routers import SimpleRouter


router = SimpleRouter()
router.register(r'users', UserViewSet)

register 有三个参数

  • prefix(必需) 此组路由的url前缀
  • viewset(必需) 处理请求的viewset类
  • base_name(可选) 如果视图集不包括queryset属性,那么在注册视图集时必须设置base_name也就是viewset 没有自定义model 或 get_queryset方法时,必须填写此属性

生成的路由

  • URL pattern: ^users/$ Name: ‘user-list’
  • URL pattern: ^users/{pk}/$ Name: ‘user-detail’

在路由中的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 方法一:
router = routers.SimpleRouter()
router.register(r'users', UserViewSet)
router.register(r'accounts', AccountViewSet)

urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
]

urlpatterns += router.urls

# 方法二:
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^', include(router.urls)),
]

urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include(router.urls, namespace='api')),
]

额外连接和操作

用@detail_route或@list_route装饰的视图集上的任何方法也将被路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class TestViewSet(viewsets.ViewSet):
permission_classes = []

from rest_framework.decorators import detail_route, list_route

# 生成的路由:^books/latest/$ name: book-latest
@action(methods=['get'], detail=False)
def latest(self, request):
...

# 生成的路由:^books/{pk}/read/$ name: book-read
@action(methods=['put'], detail=True)
def read(self, request, pk):
...

# 如果要自定义路由名,使用url_path参数定义,旧版本使用detail_route
@detail_route(methods=['get'], url_path='zb')

自定义组名和正则

1
2
3
class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
lookup_field = 'my_model_id'
lookup_value_regex = '[0-9a-f]{32}'

额外的action

我们知道, viewset里面我们可以通过继承不同的mixins来实现列表,详情,增加,修改,部分修改,删除种不同功能的接口。

可是在实际情况中,我们需要的不仅仅是这些,所以,我们需要额外的url来路由。于是引入了action装饰器,我们可以在viewset中添加额外的路由了,使用方法:

在之前旧的版本使用的是detail_route,list_route连个装饰器来添加额外的路由,用来区别url中是否有pk字段。action装饰器则是通过detail字段来区别

1
2
3
4
5
6
7
8
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):

使用上面action生成的url是 ^users/{pk}/set_password/$。 如果不想使用方法的名字来做路由,可以在action中指定url_name。

ExtendedDefaultRouter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from rest_framework_extensions.routers import ExtendedDefaultRouter


router.register(r'/we_chat', WeChatPayViewSet, 'we_chat')


class WeChatPayViewSet(viewsets.ViewSet):
permission_classes = (IsAuthenticated,)

@action(methods=["POST"], is_for_list=True)
def app_pay(self, request, *args, **kwargs):


# 当viewset使用@action
class TestViewSet(viewsets.ViewSet):

model = EStoreOrder

@action(methods=['GET'])
def test(self, request, *args, **kwargs):
return Response('ok')

# 生成的路由为
^api/estore/test/(?P<pk>[^/.]+)/test/$ [name='estoreorder-test']
^api/estore/test/(?P<pk>[^/.]+)/test/\.(?P<format>[a-z0-9]+)$ [name='estoreorder-test']

当使用
@action(methods=['GET'], is_for_list=True)
生成的路由为
^api/estore/test/test/$ [name='estoreorder-test-list']
^api/estore/test/test/\.(?P<format>[a-z0-9]+)$ [name='estoreorder-test-list']

路由router形成URL的方式

SimpleRouter

DefaultRouter


Django 路由(SimpleRouter, DefaultRouter,ExtendedDefaultRouter)
https://flepeng.github.io/021-Python-32-框架-Django-Django-路由(SimpleRouter,-DefaultRouter,ExtendedDefaultRouter)/
作者
Lepeng
发布于
2021年8月8日
许可协议