DRF权限控制:禁止用户关联不属于自身的对象
解决方案:验证创建Account时关联的Bank属于当前用户
方法一:序列化器字段级验证
这是最直接的处理方式,在Account的序列化器里添加针对bank字段的自定义校验逻辑:
# serializers.py from rest_framework import serializers from .models import Account, Bank class AccountSerializer(serializers.ModelSerializer): class Meta: model = Account fields = ['id', 'bank', 'user'] # 按需补充其他字段 def validate_bank(self, value): # 从请求上下文拿到当前用户 current_user = self.context['request'].user # 校验传入的bank所属用户是否和当前用户一致 if value.user != current_user: raise serializers.ValidationError("只能关联你自己名下的银行账户") return value
DRF会自动调用以validate_<字段名>命名的方法做字段校验,这里直接比对银行账户的归属用户,不通过就抛出验证错误。
方法二:视图集create方法中校验
如果不想在序列化器里处理,也可以在Account的视图集里重写create方法,提前做校验:
# views.py from rest_framework import viewsets, status from rest_framework.response import Response from .models import Account, Bank from .serializers import AccountSerializer class AccountViewSet(viewsets.ModelViewSet): queryset = Account.objects.all() serializer_class = AccountSerializer def get_queryset(self): return self.queryset.filter(user=self.request.user) def create(self, request, *args, **kwargs): bank_id = request.data.get('bank') if not bank_id: return Response({"bank": "此字段为必填项"}, status=status.HTTP_400_BAD_REQUEST) try: # 直接查询属于当前用户的目标bank bank = Bank.objects.get(id=bank_id, user=request.user) except Bank.DoesNotExist: return Response({"bank": "指定的银行不存在或不属于你"}, status=status.HTTP_400_BAD_REQUEST) # 校验通过,走默认创建流程 return super().create(request, *args, **kwargs)
这里直接在查询bank时就带上用户过滤,既能验证银行存在,又能确保归属正确,一步到位。
额外优化建议
- 可以把Account序列化器里的
user字段设为只读,创建时自动赋值当前用户,避免前端传入错误值:
# 在AccountSerializer的create方法里添加 def create(self, validated_data): validated_data['user'] = self.context['request'].user return super().create(validated_data)
同时在序列化器的Meta里把user加入read_only_fields:
class Meta: model = Account fields = ['id', 'bank', 'user'] read_only_fields = ['user']
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

