DRF框架(十一)——路由解读。action注解的声明有什么作用

2021-03-02 14:43:15 浏览数 (1)

这里写目录标题

  • REST framework提供了两个router
  • 1. 使用方法
  • 2. 视图集中附加action的声明

试图集里面,每增加一个额外的行为,那么就要写一个新的路由,这个是比较麻烦的。

代码语言:javascript复制
# router = SimpleRouter()  # 创建路由器(路由器只能结束视图集一起使用)
# 默认只为标准了增删改查行为生成路由信息,如果想让自定义的行为也生成路由需要在自定义行为上用action装饰进行装饰
# router.register(r'books', views.BookViewSet)  # 注册路由
# urlpatterns  = router.urls  # 把生成好的路由拼接到urlpatterns

用以上的方法写路由,只能是view里面继承了试图集之后才可以使用,并且只是生成默认的增删改查的接口。如果是新增加的其他的动作的方法,是不能自动生成路由的,那么如果处理新增加的动作呢?

REST framework提供了两个router

SimpleRouter DefaultRouter

1. 使用方法

代码语言:javascript复制
1) 创建router对象,并注册视图集,例如

from rest_framework import routers

router = routers.SimpleRouter()
router.register(r'books', BookInfoViewSet, base_name='book')
register(prefix, viewset, base_name)

prefix 该视图集的路由前缀
viewset 视图集
base_name 路由名称的前缀
如上述代码会形成的路由如下:

^books/$    name: book-list
^books/{pk}/$   name: book-detail
2)添加路由数据

可以有两种方式:

urlpatterns = [
    ...
]
urlpatterns  = router.urls
或

urlpatterns = [
    ...
    url(r'^', include(router.urls))
]

2. 视图集中附加action的声明

代码语言:javascript复制
在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,
需要使用rest_framework.decorators.action装饰器。

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

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

methods: 声明该action对应的请求方式,列表传递
detail: 声明该action的路径是否与单一资源对应,及是否是xxx/<pk>/action方法名/
True 表示路径格式是xxx/<pk>/action方法名/
False 表示路径格式是xxx/action方法名/
代码语言:javascript复制
class BookViewSet(ModelViewSet):
    """视图集"""
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoModelSerializer

    # 查询最后一本书  books/latest/  get:latest
    @action(methods=['get'], detail=False)
    # @action(methods=[指定下面的行为接收什么请求], detail=是不是详情视图如果是不详情视图就是 books/latest)
    def latest(self, request):
        """
        返回最新的图书信息
        """
        book = BookInfo.objects.latest('id')  # 获取最后一本书
        serializer = self.get_serializer(book)
        return Response(serializer.data)

    # books/pk/read/
    @action(methods=['put'], detail=True)
    def read(self, request, pk):
        """
        修改图书的阅读量数据
        """
        book = self.get_object()
        book.bread = request.data.get('bread')
        book.save()
        serializer = self.get_serializer(book)
        return Response(serializer.data)

0 人点赞