DRF之路由控制

  • 参考网址

https://www.cnblogs.com/yangyi215/p/15041610.html

  • 引入场景,继承 ModelViewSet 快速实现'增删改查',手动配置路由
# views
# ModelViewSet内部实现了5个方法
'''
    - 'get':'retrieve'(传pk),'get':'list'

    - 'post':'create'

    - 'put':'update'(传pk)

    - 'delete':'destroy'(传pk)

    
'''
class BookInfoViewSet(ModelViewSet):
    authentication_classes = []
    permission_classes = []

    queryset = BookInfo.objects.get_queryset()
    serializer_class = BookInfoserializer

### urls
......
urlpatterns = [
    ......
    # viewset
    url(r'^book_set/(?P<pk>\d+)', views.BookInfoViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
    url(r'^book_set/', views.BookInfoViewSet.as_view(actions={'get':'list','post':'create'})),
]

  • 如果觉得配置路由的方法,有点繁琐,那么我们有没有更简单的配置路由的方式?
    DRF提供了一种更简单的配置路由的方式
    自动生成继承视图类ModelViewSet的路由,书写方式如下
from django.conf.urls import url
# 导入 routers模块
from rest_framework import routers

# 生成 router实例
router = routers.SimpleRouter()
# 调用register('前缀','继承自ViewSet视图类','别名')方法注册,自动生成路由
router.register(prefix='book_set',viewset=views.BookInfoViewSet,basename='book_set')
# router.urls: [<URLPattern '^book_set/$' [name='book_set-list']>, <URLPattern '^book_set/(?P<pk>[^/.]+)/$' [name='book_set-detail']>]


urlpatterns = [
    ......
    # viewset
    # url(r'^book_set/(?P<pk>\d+)', views.BookInfoViewSet.as_view(actions={'get':'retrieve','put':'update','delete':'destroy'})),
    # url(r'^book_set/', views.BookInfoViewSet.as_view(actions={'get':'list','post':'create'})),
]

# 加入原路由
urlpatterns += router.urls

- 效果: 和原来一模一样

- 注意事项,自动路由还有一个 router = routers.DefaultRouter()
  步骤和上面一样,会生成6个路由(用得比较少)

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

class BookInfoViewSet(ModelViewSet):
    authentication_classes = []
    permission_classes = []

    queryset = BookInfo.objects.get_queryset()
    serializer_class = BookInfoserializer

    @action(methods=['get'], detail=True)
    # def get_data(self, request, pk):
    def get_data(self, request, *args,**kwargs):
        # print(pk)
        queryset = self.get_queryset()[0:2]  # 切片:截取两条数据
        serializer = self.get_serializer(instance=queryset, many=True)
        return Response(serializer.data)

'''
- 返回同样的数据,一个带pk,一个不带pk

    - detail=False 不带pk

        - http://127.0.0.1:8888/tests/book_set/get_data/

            - 返回id为1和2的数据

    - detail=True 带pk【固定写法,如果想改重写内部参数即可】

        - http://127.0.0.1:8888/tests/book_set/1/get_data/

            - - 返回id为1和2的数据
'''