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

ModelViewSet中外键关系对象级权限定义报错及方案咨询

问题分析与解决方案

先帮你拆解下当前遇到的核心问题,再一步步给出修正方案:

1. 权限类中的'FinancialAccount' object has no attribute 'owner'错误

你在IsOwnerTeam里直接访问obj.owner,但FinancialAccount模型本身并没有owner字段——它是通过client外键关联到Client,而Client才关联Team作为owner。所以必须通过关联关系链来获取所属团队:

class IsOwnerTeam(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        # 用主键判断更可靠,避免团队名称重复的情况
        user_team_ids = request.user.teams.values_list('pk', flat=True)
        # 走关联链:FinancialAccount -> Client -> Team
        return obj.client.owner.pk in user_team_ids

2. get_queryset中的语法错误

你的get_queryset里有两处明显问题:

  • 未定义的accounts变量,实际应该用前面查询到的clients
  • 过滤字段写错了,FinancialAccount的外键是client,不是account

修正后的代码:

class FinancialAccountViewSet(viewsets.ModelViewSet):
    serializer_class = FinancialAccountSerializer
    permission_classes = (IsOwnerTeam, )
    
    def get_queryset(self):
        teams = self.request.user.teams.all()
        clients = Client.objects.filter(owner__in=teams)
        # 用select_related提前加载关联数据,减少数据库查询次数
        return FinancialAccount.objects.filter(client__in=clients).select_related('client__owner')

3. 序列化器中的小疏漏

你在FinancialAccountSerializer的get_owner方法里写了return client.owner.name,这里的client没有定义,应该用传入的obj参数:

def get_owner(self, obj):
    return obj.client.owner.name

额外优化建议

如果多个视图都需要判断用户是否属于资源所属团队,可以把逻辑封装成工具函数,提升代码复用性:

def user_belongs_to_resource_team(user, resource):
    """判断用户是否在资源所属的团队中"""
    user_team_ids = user.teams.values_list('pk', flat=True)
    return resource.client.owner.pk in user_team_ids

之后在权限类里直接调用这个函数即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:31:06