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
相关产品推荐
相关产品推荐

