第四篇:DRF之路由控制

第四篇:DRF之路由控制

一、手动配置路由

我们现在视图类中这样进行书写。

"""views.py"""
"""基于ModelViewSet实现5个接口"""
from rest_framework.viewsets import ModelViewSet
class BookView5(ModelViewSet):  # 我们点击去发现,5个接口都有。
    queryset = models.Book.objects.all()
    serializer_class = BookSerializers

我们以前配置路由的方式如下所示。

# 基于ModelViewSet(继承了ViewSetMixin)实现5个接口
url(r'^books5/(?P<pk>\d+)', views.BookView5.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
url(r'^books5/', views.BookView5.as_view(actions={'get':'list','post':'create'})),

二、自动配置路由

我们觉得配置路由的方法,有点繁琐,那么我们有没有更简单的配置路由的方式?DRF提供了一种更简单的配置路由的方式。

自动生成继承视图类ModelViewSet的路由,书写方式如下。

  • urls.py
"""第一种方式:routers.SimpleRouter()"""  # 生成两个路由【推荐使用】
# 第一步:导入routers模块
from rest_framework import routers
# routers.DefaultRouter
# 第二步:有两个类,实例化得到对象  routers.SimpleRouter() 和 routers.DefaultRouter()
router = routers.SimpleRouter()
# 第三步:注册  router.register('前缀','继承自ViewSet视图类','别名')
router.register(prefix='books', viewset=views.BookView)  # books后不要加斜杠
print(router.urls)
"""
router.urls = [
<RegexURLPattern book-list ^books/$>, 
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)/$>
]
"""
urlpatterns = [
    url(r'^admin/', admin.site.urls),
]
# 第四步:自动生成的路由,加入到原路由中
urlpatterns += router.urls  # 或者 urlpatterns.extend(route.urls)


"""第二种方式:routers.DefaultRouter()"""  # 生成6个路由,但是没啥用【不推荐】
from rest_framework import routers

router = routers.DefaultRouter()
router.register(prefix='books', viewset=views.BookView)
print(router.urls)
"""
router.urls = [
<RegexURLPattern api-root ^$>,   # 首页
<RegexURLPattern book-list ^books/$>,
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)/$>, 
<RegexURLPattern book-list ^books\.(?P<format>[a-z0-9]+)/?$>, 
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)\.(?P<format>[a-z0-9]+)/?$>, 
<RegexURLPattern api-root ^\.(?P<format>[a-z0-9]+)/?$>
]
"""
urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

urlpatterns += router.urls

三、action的使用

虽然现在能够自动化,生成路由,但是又引出一个问题,如果我们想给继承自ModelViewSet的视图类中定义的函数也添加路由,那么我们该如何操作呢?这就引出了action装饰器。

如果我们直接再类中添加自定义函数,是不会自动添加路由的。

from rest_framework.viewsets import ModelViewSet
class BookView(ModelViewSet):  # 我们点击去发现,5个接口都有。
    queryset = models.Book.objects.all()
    serializer_class = BookSerializers
	# 自定义函数
    def get_data(self, request, pk):
        print(pk) 
        book_queryset = self.get_queryset()[0:2]  # 切片:截取两条数据
        book_ser = self.get_serializer(book_queryset, many=True)
        return Response(book_ser.data)

使用装饰器action进行装饰。我们观看action的源码,可以发现。

action的使用方式如下所示。

"""views.py"""  # detail=False
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
class BookView(ModelViewSet):  # 我们点击去发现,5个接口都有。
    queryset = models.Book.objects.all()
    serializer_class = BookSerializers

    # 添加action装饰器
    """
    methods第一个参数,传一个列表,列表中放请求方式,
    detail=False  <RegexURLPattern book-get-data ^books/get_data/$>
    """
    @action(methods=['get', 'post'], detail=False)
    def get_data(self, request):
        book_queryset = self.get_queryset()[0:2]  # 切片:截取两条数据
        book_ser = self.get_serializer(book_queryset, many=True)
        return Response(book_ser.data)
    
    
"""urls.py中生成路由"""
router.urls = [
<RegexURLPattern book-list ^books/$>, 
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)/$>,
<RegexURLPattern book-get-data ^books/get_data/$>    # detail=False的路由显示效果
]

如果我们将detail=Ture,我们可以得到这样的路由。

"""views.py"""
@action(methods=['get', 'post'], detail=True)


"""urls.py"""
router.urls = [
<RegexURLPattern book-list ^books/$>, 
<RegexURLPattern book-detail ^books/(?P<pk>[^/.]+)/$>, 
<RegexURLPattern book-get-data ^books/(?P<pk>[^/.]+)/get_data/$>  # detail=True的路由显示效果
]

# detail=False 不带pk
# detail=True 带pk【固定写法,如果想改重写内部参数即可】。
posted @ 2021-07-21 21:10  YangYi215  阅读(203)  评论(0编辑  收藏  举报