You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django看板项目:重复添加用户无响应且HTTP 201异常排查

问题分析

你的核心问题是:CreateAPIView的perform_create方法不支持直接返回Response对象,框架会忽略这个返回值,继续执行默认的创建流程。所以你在方法里写的各种错误提示和自定义成功响应都不会生效,只会返回框架默认的201 Created状态。

解决方案

重写create方法来处理所有逻辑——这个方法才是DRF负责生成并返回响应的入口,能完全控制返回内容和状态码。

修改后的views.py代码:

from rest_framework import generics, permissions, status
from rest_framework.response import Response
from .models import Board, BoardUser
from .serializer import BoardUserSerializer

class CreateBoardUserView(generics.CreateAPIView):
    queryset = BoardUser.objects.all()
    serializer_class = BoardUserSerializer
    permission_classes = [permissions.IsAuthenticated]

    def create(self, request, *args, **kwargs):
        # 从URL提取看板ID
        board_id = self.kwargs.get('board_id')
        # 获取当前认证用户
        current_user = self.request.user
        # 从请求数据获取待添加用户ID
        user_id = self.request.data.get('user')

        # 检查看板是否存在(补充原代码缺失的异常处理)
        try:
            board_instance = Board.objects.get(pk=board_id)
        except Board.DoesNotExist:
            return Response({'message': '看板不存在'}, status=status.HTTP_404_NOT_FOUND)

        # 转换用户ID为User实例
        try:
            user_instance = current_user.__class__.objects.get(pk=user_id)
        except current_user.__class__.DoesNotExist:
            return Response({'message': '无效的用户ID'}, status=status.HTTP_400_BAD_REQUEST)

        # 检查当前用户是否是看板所有者
        board_user = BoardUser.objects.filter(board=board_instance, user=current_user).first()
        if not board_user or not board_user.is_owner:
            return Response({'message': '你不是该看板的所有者,无权添加用户'}, status=status.HTTP_403_FORBIDDEN)

        # 检查用户是否已被添加到看板
        if BoardUser.objects.filter(board=board_instance, user=user_instance).exists():
            return Response({'message': '该用户已在看板中'}, status=status.HTTP_400_BAD_REQUEST)

        # 执行创建逻辑
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save(board=board_instance, user=user_instance)
        return Response({'message': '用户添加成功'}, status=status.HTTP_201_CREATED)
额外优化建议
  • 数据库层面防重复:在BoardUser模型添加联合唯一约束,从根源避免重复记录:
class BoardUser(models.Model):
    board = models.ForeignKey(Board, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    is_owner = models.BooleanField(default=False)

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['board', 'user'], name='unique_board_user')
        ]
  • 简化序列化器:因为在视图里已手动传入board和user实例,可将这两个字段设为只读,避免前端传入无效值:
class BoardUserSerializer(serializers.ModelSerializer):
    board = serializers.PrimaryKeyRelatedField(read_only=True)
    user = serializers.PrimaryKeyRelatedField(read_only=True)
    is_owner = serializers.BooleanField(read_only=True)

    class Meta:
        model = models.BoardUser
        fields = ('board', 'user', 'is_owner')

内容的提问来源于stack exchange,提问作者mkownak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 12:33:19