我正在创建一个类似看板的 Scrum 板。我想将用户添加到所述板上。我从 url 获取板的 id,然后我想传递用户的 id。我已设法避免重复,但返回后没有任何回复。在 django 调试工具中,即使没有在数据库中创建重复项,我也会在每个请求上收到 HTTP 201 Created
模型.py
class Board(models.Model):
name = models.CharField(max_length=250)
description = models.TextField()
create_date = models.DateField(auto_now=True)
due_date = models.DateField()
def __str__(self):
return self.name
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)
序列化器.py
class BoardUserSerializer(serializers.ModelSerializer):
#board = BoardSerializer(read_only=True)
#user = UserSerializer(read_only=True)
is_owner = serializers.BooleanField(read_only=True)
class Meta:
model = models.BoardUser
fields = (
'board',
'user',
'is_owner',
)
views.py
class CreateBoardUserView(generics.CreateAPIView):
queryset = BoardUser.objects.all()
serializer_class = BoardUserSerializer
permission_classes = [permissions.IsAuthenticated]
def perform_create(self, serializer):
# Extract board ID from URL
board_id = self.kwargs.get('board_id')
# Get the authenticated user
user = self.request.user
# Get the user ID from the request data
user_id = self.request.data.get('user')
# Retrieve the board instance directly from the database
board_instance = Board.objects.get(pk=board_id)
try:
# Convert user ID to User instance
user_instance = User.objects.get(pk=user_id)
except User.DoesNotExist:
return Response({'message': 'Invalid user ID provided.'}, status=status.HTTP_400_BAD_REQUEST)
# Check if the user is the owner of the board
board_user = BoardUser.objects.filter(board=board_instance, user=user).first()
if not board_user or not board_user.is_owner:
return Response({'message': 'You are not the owner of this board.'}, status=status.HTTP_403_FORBIDDEN)
# Check if the user is already assigned to this board
if BoardUser.objects.filter(board=board_instance, user=user_instance).exists():
return Response({'message': 'User is already assigned to this board.'}, status=status.HTTP_400_BAD_REQUEST)
# Avoid duplicates
try:
serializer.save(board=board_instance, user=user_instance)
return Response({'message': 'Board user created successfully.'}, status=status.HTTP_201_CREATED)
except Exception as e:
return Response({'message': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
您的 CreateBoardUserView 似乎具有检查重复项和权限的正确想法,但您从 Perform_create 方法中返回的 Response 对象可能无法按预期工作。 Django Rest Framework (DRF) 中的 Perform_create 方法不需要返回 Response 对象;相反,它希望您执行保存操作或引发 DRF 可以捕获和处理的异常。
要解决您的问题,您应该引发 ValidationError 而不是返回 Response 对象。 DRF 框架将捕获这些异常并自动将它们转换为适当的 HTTP 响应。
这是您的 Perform_create 方法的更正版本:
from rest_framework.exceptions import ValidationError, PermissionDenied
from rest_framework.response import Response
from rest_framework import status
# Other imports ...
class CreateBoardUserView(generics.CreateAPIView):
# ... your existing code ...
def perform_create(self, serializer):
board_id = self.kwargs.get('board_id')
user = self.request.user
user_id = self.request.data.get('user')
board_instance = Board.objects.get(pk=board_id)
# Check for user existence and handle User.DoesNotExist within the serializer
serializer.is_valid(raise_exception=True)
user_instance = serializer.validated_data['user']
# Check if the user is the owner of the board
board_user = BoardUser.objects.filter(board=board_instance, user=user).first()
if not board_user or not board_user.is_owner:
raise PermissionDenied({'message': 'You are not the owner of this board.'})
# Check if the user is already assigned to this board
if BoardUser.objects.filter(board=board_instance, user=user_instance).exists():
raise ValidationError({'message': 'User is already assigned to this board.'})
# No exceptions raised: save the instance
serializer.save(board=board_instance, user=user_instance)
# The response will be handled by DRF, no need to return it here.
请注意:
当当前用户不是所有者时,我们会引发 PermissionDenied 异常。 当用户已分配到面板时,我们会引发 ValidationError 异常。 我们依靠序列化器的 is_valid() 方法来检查用户是否存在以及任何其他验证规则。 实例的实际保存(通过serializer.save())是在所有检查通过后完成的。 DRF 将处理异常并返回适当的响应。 通过引发异常而不是在 Perform_create 中返回 Response 对象,DRF 的框架将自动处理异常并生成合适的 HTTP 响应以返回给客户端。这应该可以解决您遇到的每个请求都返回 HTTP 201 Created 状态代码的问题。