如何在Django REST Framework中通过单次API调用实现记录查询与更新
实现单次API调用查询并更新Task状态
要完成单次API调用查询一条NEW状态的Task并将其更新为INPROGRESS,你需要在Django REST Framework的ViewSet中自定义一个action,具体实现如下:
1. 修改view.py,添加自定义Action
from rest_framework.decorators import action from rest_framework.response import Response from rest_framework import status from django.db import transaction from django.utils import timezone class TaskViewSet(viewsets.ModelViewSet): queryset = Task.objects.all() serializer_class = TaskSerializer permission_classes = [permissions.IsAuthenticated] @action(detail=False, methods=['post']) def claim_task(self, request): # 事务+行锁避免并发场景下重复分配任务 with transaction.atomic(): # 查询第一条NEW状态任务并加锁 task = Task.objects.filter(status='NEW').select_for_update().first() if not task: return Response({"message": "无待处理的NEW任务"}, status=status.HTTP_404_NOT_FOUND) # 更新状态及操作信息 task.status = 'INPROGRESS' task.update_date = timezone.now().date() task.update_id = request.user.id # 基于当前登录用户ID更新 task.save() # 返回更新后的任务数据 serializer = self.get_serializer(task) return Response(serializer.data, status=status.HTTP_200_OK)
2. 关键细节说明
- 并发控制:
select_for_update()会对查询到的任务行加锁,结合transaction.atomic()确保同一时间只有一个请求能修改该任务,避免重复分配。 - REST规范适配:用
@action(detail=False)声明这是一个非详情接口,请求方法设为POST,符合修改资源的REST语义。 - 字段补充更新:示例中同步更新了
update_date和update_id,用于记录任务领取的时间和操作人,可根据业务需求调整。 - 异常场景处理:无
NEW状态任务时返回404状态码及明确提示,便于调用方处理。
3. API调用方式
通过POST请求访问接口,路径一般为/tasks/claim_task/(具体路由前缀取决于你的项目配置),请求无需额外参数(操作人信息已通过登录用户自动获取)。
内容的提问来源于stack exchange,提问作者Learner
相关产品推荐
相关产品推荐

