Django REST framework(十)路由集routers的使用

Django REST framework(九)-视图集ViewSet、GenericViewSet、ModelViewSet、ReadOnlyModelViewSet_simpleyako的博客-CSDN博客

对于上次学到的视图集来说,虽然我们在编写视图逻辑代码时通过继承ModelViewSet后只需提供序列化器模型对象查询集即可省去增删改查(查询所有数据)这五个常用的接口大量的代码。但是我们在编写路由时,又有些许的麻烦,所有drf为我们提供了routers路由集,为我们在编写视图代码继承视图集时提供自动生成路由的功能。

如下图是继承视图集ModelViewSet后编写的代码及路由。

class _ModelViewSet(ModelViewSet):
    queryset = BookInfo.objects.all()
    serializer_class = BookSerializer
 
#
# --------------------ModelViewSet-----------------------------------------
    path('demo/books/', _ModelViewSet.as_view({
        'get': 'list',
        'post': 'create'
    })),
    re_path(r'^demo/books/(?P<pk>\d+)/$', _ModelViewSet.as_view({
        "get": 'retrieve',
        'delete': 'destroy',
        'put': 'update'
    })),

对于视图集,我们除了可以自己手动指明请求方式动作action(视图名)之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。如果是非视图集,不需要使用路由集routers  

一、DefaultRouter 

from rest_framework.routers.DefaultRouter

如下:通过DefaultRouter自动生成路由步骤(默认自动生成list、create、delete、update、retrieve五个视图函数的路由):

  • 创建DefaultRouter实例对象routers
  • 通过实例对象routers.register(prefix, viewset, basename=None)方法进行自动生成路由
    • prefix:url路径
    • viewset:继承视图集的视图
    • basename:url路径的别名
  • 将自动生成的路由添加到urlpatterns列表中去

1、代码

# -------------------DefaultRouter-----------------------------------------
from rest_framework.routers import DefaultRouter

# 1.实例化DefaultRouter路由对象
routers = DefaultRouter()

# 2.指定继承视图集的视图,自动生成路由
routers.register('demo/books', _ModelViewSet, basename='demo/books/')
for url in routers.urls:
    print(url)
# 3.将生成的路由添加到urlpatterns中去
urlpatterns += routers.urls

2、路由

"""
1、对应创建模型对象和查询所有模型对象数据的路由
<URLPattern '^demo/books/$' [name='demo/books/-list']>


2、对应更改、查询、删除单个模型对象的路由
<URLPattern '^demo/books\.(?P<format>[a-z0-9]+)/?$' [name='demo/books/-list']>
<URLPattern '^demo/books/(?P<pk>[^/.]+)/$' [name='demo/books/-detail']>
<URLPattern '^demo/books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='demo/books/-detail']>

3、对应访问url路径http://127.0.0.1:8000时显示
    {
        "demo/books": "http://127.0.0.1:8000/demo/books/"
    }
<URLPattern '^$' [name='api-root']>


4、对应访问url路径http://127.0.0.1:8000\时显示
    {
        "demo/books": "http://127.0.0.1:8000/demo/books/"
    }
<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>
"""

3、测试

对应根路径的路由

 <URLPattern '^$' [name='api-root']>

<URLPattern '^\.(?P<format>[a-z0-9]+)/?$' [name='api-root']>

对应更改、查询、删除单个模型对象路径的路由
<URLPattern '^demo/books\.(?P<format>[a-z0-9]+)/?$' [name='demo/books/-list']>
<URLPattern '^demo/books/(?P<pk>[^/.]+)/$' [name='demo/books/-detail']>
<URLPattern '^demo/books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$' [name='demo/books/-detail']>

 对应创建模型对象和查询所有模型对象数据的路径路由
<URLPattern '^demo/books/$' [name='demo/books/-list']>

 二、SimpleRouter

使用方式与DefaultRouter一致的。只是少两个根目录url路径以及将四个url路径压缩为两个。

1、代码

# -------------------SimpleRouter-----------------------------------------
from rest_framework.routers import SimpleRouter

# 1.实例化DefaultRouter路由对象
routers = SimpleRouter()

# 2.指定继承视图集的视图,自动生成路由
routers.register('demo/books', _ModelViewSet, basename='demo/books/')
for url in routers.urls:
    print(url)
# 3.将生成的路由添加到urlpatterns中去
urlpatterns += routers.urls

2、路由

1、对应创建模型对象和查询所有模型对象数据的路由
<URLPattern '^demo/books/$' [name='demo/books/-list']>
2、对应更改、查询、删除单个模型对象的路由
<URLPattern '^demo/books/(?P<pk>[^/.]+)/$' [name='demo/books/-detail']>

3、测试

缺少的根路径路由

 1、对应创建模型对象和查询所有模型对象数据的路由
<URLPattern '^demo/books/$' [name='demo/books/-list']>

 2、对应更改、查询、删除单个模型对象的路由
<URLPattern '^demo/books/(?P<pk>[^/.]+)/$' [name='demo/books/-detail']>

三、视图集中附加action的声明

rest_framework.decorators.action

在视图集中,如果想要让Router自动帮助我们自定义出除开list、create、delete、update、retrieve)这五个视图函数的url路由外的路由,因为可能一个视图中不止这些方法。则我们需要在视图集中使用action装饰器。

以action装饰器装饰的视图函数方法名会作为action动作名,与list、retrieve等同。

action装饰器可以接收两个参数:

  • methods: 声明该action对应的请求方式,列表参数

  • detail: 声明该action的路径是否与单一资源对应

    路由前缀/<pk>/action方法名/
    • True 表示路径格式是xxx/<pk>/action方法名/

    • False 表示路径格式是xxx/action方法名/

  • url_path:声明该action的路由尾缀。

  1、不是单一资源

代码

class _ModelViewSet(ModelViewSet):
    def get_serializer_class(self):
        if self.action == 'get_books_name':
            return BookNameSerializer
        else:
            return BookSerializer

    queryset = BookInfo.objects.all()

    @action(methods=['GET'], detail=False)
    def get_books_name(self, request):
        names = self.get_queryset()
        ser = self.get_serializer(instance=names, many=True)
        return Response(data=ser.data)

自动生成的路由

<URLPattern '^demo/books/get_books_name/$' [name='demo/books/-get-books-name']>

其中自动生成的后缀路由get_books_name/就是视图函数名,demo/books/为以下生成视图集路由时的前缀

routers.register('demo/books', _ModelViewSet, basename='demo/books/')

如果想后缀名/login不是由自动生成路由时的函数名,可以通过url_path自定义后缀名

class _ModelViewSet(ModelViewSet):
    def get_serializer_class(self):
        if self.action == 'get_books_name':
            return BookNameSerializer
        else:
            return BookSerializer

    queryset = BookInfo.objects.all()

    @action(methods=['GET'], detail=False, url_path='get_name')
    def get_books_name(self, request):
        names = self.get_queryset()
        ser = self.get_serializer(instance=names, many=True)
        return Response(data=ser.data)

<URLPattern '^demo/books/get_name/$' [name='demo/books/-get-books-name']>

 

 

2、单一资源

代码

from rest_framework.decorators import action
from .Serializer import BookNameSerializer


class _ModelViewSet(ModelViewSet):
    def get_serializer_class(self):
        if self.action == 'get_books_name':
            return BookNameSerializer
        else:
            return BookSerializer

    queryset = BookInfo.objects.all()
    @action(methods=['GET'], detail=True, url_path='get_name')
    def get_books_name(self, request, pk):
        names = self.get_object()
        ser = self.get_serializer(instance=names)
        return Response(data=ser.data)

自动生成的路由

<URLPattern '^demo/books/(?P<pk>[^/.]+)/get_name/$' [name='demo/books/-get-books-name']>

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值