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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 20:39:20