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): return Response({'msg': '这是一个收入汇总报表'})
@action(detail=True, methods=['post']) def approve(self, request, pk=None): return Response({'msg': f'收入 {pk} 已被审批'})
@action(detail=True, methods=['put']) def lock(self, request, pk=None): 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 下。