Django中如何限制仅任务作者可选NEW/COMPLETED状态,执行者不可选?
实现方案
1. 动态调整序列化器的状态选项
修改serializers.py,在序列化器初始化时根据当前用户身份过滤可选的状态,确保前端只展示用户有权选择的选项:
from rest_framework import serializers from .models import Tasks from django.contrib.auth import get_user_model User = get_user_model() class TasksSerializer(serializers.ModelSerializer): author = serializers.SlugRelatedField(read_only=True, slug_field='username') performers = serializers.SlugRelatedField(many=True, read_only=True, slug_field='username') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) user = self.context['request'].user instance = kwargs.get('instance') if instance: is_author = instance.author == user is_performer = user in instance.performers.all() # 执行者仅能选择'in progress'和'on finish' if not is_author and is_performer: allowed_statuses = [('in progress', 'in progress'), ('on finish', 'on finish')] self.fields['status'].choices = allowed_statuses class Meta: model = Tasks fields = '__all__'
2. 后端验证状态修改权限
在views.py中重写update方法,增加后端校验,防止用户绕过前端限制直接提交非法状态:
from rest_framework import viewsets, status from rest_framework.response import Response from .models import Tasks from .serializers import TasksSerializer from rest_framework.permissions import IsAuthenticated class TasksViewSet(viewsets.ModelViewSet): permission_classes = [IsAuthenticated] queryset = Tasks.objects.all().select_related('author').prefetch_related('performers') serializer_class = TasksSerializer filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filterset_fields = ['status'] search_fields = ['title', 'text'] ordering_fields = ['date_create', 'date_update', 'author', 'status'] def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() user = request.user # 非作者的执行者尝试设置NEW/COMPLETED时直接拒绝 if instance.author != user and user in instance.performers.all(): new_status = request.data.get('status') if new_status in ['new', 'completed']: return Response( {'error': '执行者无法设置NEW或COMPLETED状态'}, status=status.HTTP_403_FORBIDDEN ) return super().update(request, *args, **kwargs)
3. 优化权限控制(可选)
如果原IsPerformers权限类无法覆盖作者的访问权限,替换为自定义权限类,确保作者和执行者都能操作对应任务:
from rest_framework.permissions import BasePermission class IsAuthorOrPerformer(BasePermission): def has_object_permission(self, request, view, obj): return obj.author == request.user or request.user in obj.performers.all()
然后在视图中更新权限配置:
permission_classes = [IsAuthenticated, IsAuthorOrPerformer]
核心逻辑说明
- 序列化层修改:控制前端展示的可选状态,提升用户交互体验
- 视图层校验:从后端拦截非法状态修改,保证数据安全
- 权限类优化:确保只有任务的作者和执行者具备操作权限
内容的提问来源于stack exchange,提问作者Andrii
相关产品推荐
相关产品推荐

