0%

Django-Rest-Framework-ViewSet-@action-自定义动作详解

Django Rest Framework ViewSet @action 自定义动作详解

1. @action 的作用

  • ViewSet 默认只支持 list/retrieve/create/update/destroy 这些标准动作。
  • 通过 @action 装饰器可以给 ViewSet 添加自定义接口(动作)。
  • 支持 GET / POST / PUT / PATCH / DELETE 方法。

2. @action 路由映射规则

detail 参数 URL 形式 HTTP 方法 对应函数 说明
detail=False /incomes/custom_action/ 任意 IncomeViewSet.custom_action() 针对列表的自定义动作
detail=True /incomes/{pk}/custom_action/ 任意 IncomeViewSet.custom_action() 针对某个对象的自定义动作
  • detail=False 表示这个动作是列表级别(不需要 pk)
  • detail=True 表示这个动作是单个对象级别(需要 pk)

3. 示例代码

from rest_framework import viewsets, permissions
from rest_framework.decorators import action
from rest_framework.response import Response

class IncomeViewSet(viewsets.ViewSet):
permission_classes = [permissions.IsAuthenticated]

@action(detail=False, methods=['get'])
def report(self, request):
# GET /incomes/report/
return Response({'msg': '这是一个收入汇总报表'})

@action(detail=True, methods=['post'])
def approve(self, request, pk=None):
# POST /incomes/{pk}/approve/
return Response({'msg': f'收入 {pk} 已被审批'})

@action(detail=True, methods=['put'])
def lock(self, request, pk=None):
# PUT /incomes/{pk}/lock/
return Response({'msg': f'收入 {pk} 已被锁定'})

4. URL 映射对应表(@action 版)

URL HTTP 方法 调用方法 说明
/incomes/report/ GET IncomeViewSet.report() 自定义列表级别动作
/incomes/{pk}/approve/ POST IncomeViewSet.approve(pk) 自定义对象级别动作
/incomes/{pk}/lock/ PUT IncomeViewSet.lock(pk) 自定义对象级别动作

5. 请求示例

5.1 列表级别自定义动作 (detail=False)

curl -X GET http://localhost:8000/incomes/report/

→ 调用 report()

5.2 对象级别自定义动作 (detail=True)

curl -X POST http://localhost:8000/incomes/10/approve/

→ 调用 approve(pk=10)

curl -X PUT http://localhost:8000/incomes/10/lock/

→ 调用 lock(pk=10)


6. @action 小结

参数 用法
detail=False 列表级别动作,对应 URL /model_name/custom/
detail=True 单对象级别动作,对应 URL /model_name/{pk}/custom/
methods=[‘get’, ‘post’, …] 指定 HTTP 方法
  • @action 会自动帮你生成 URL 和对应的函数调用,无需手写 path() 路由
  • Router 会将这些自定义动作“挂载”到你 ViewSet 注册的基础 URL 下。