Graphene Django中仅所有者可见字段的权限控制最佳实践
最佳实践方案
针对你遇到的问题,不用创建多套UserType的最佳实践核心思路是在字段级别做权限控制,避免重复定义类型,具体方案如下:
1. 为私有字段自定义resolve方法
直接在原UserType里给fieldB和relationshipB写专属解析函数,判断当前请求用户是否是资源所有者,仅匹配时返回字段值,否则返回None(或根据需求抛出权限错误)。
示例代码:
class UserType(DjangoObjectType): class Meta: model = User fields = [ "fieldA", "fieldB", "relationshipA", "relationshipB" ] def resolve_fieldB(self, info): # self是当前User实例,info.context.user为请求发起的用户 if info.context.user == self: return self.fieldB return None def resolve_relationshipB(self, info): if info.context.user == self: return self.relationshipB return None
这种方式的优势:
- 无需额外定义
PublicUserType,一套类型覆盖所有场景 - 字段权限逻辑与字段本身绑定,维护更集中
- 关联模型(比如
relationshipA对应的模型)有私有字段时,直接在该模型的DjangoObjectType里用相同逻辑处理即可,不用重复造轮子
2. 封装权限判断逻辑(减少重复代码)
如果多个字段需要相同的权限判断,可以把逻辑封装成工具函数或装饰器,避免代码冗余:
def is_owner(user, obj): return user == obj class UserType(DjangoObjectType): # ... Meta部分省略 def resolve_fieldB(self, info): if is_owner(info.context.user, self): return self.fieldB return None def resolve_relationshipB(self, info): if is_owner(info.context.user, self): return self.relationshipB return None
如果使用graphene-django的权限装饰器,还能更简洁:
from graphene_django.permissions import permission_required class UserType(DjangoObjectType): # ... Meta部分省略 @permission_required(lambda user, obj: user == obj) def resolve_fieldB(self, info): return self.fieldB @permission_required(lambda user, obj: user == obj) def resolve_relationshipB(self, info): return self.relationshipB
3. 动态过滤返回字段(进阶场景)
如果需要批量控制大量字段的可见性,可以在Type的get_fields方法里动态过滤字段,适合字段较多的场景:
class UserType(DjangoObjectType): class Meta: model = User fields = [ "fieldA", "fieldB", "relationshipA", "relationshipB" ] @classmethod def get_fields(cls, context): fields = super().get_fields(context) # 若当前用户不是所有者,移除私有字段 if context.user != context.object: del fields["fieldB"] del fields["relationshipB"] return fields
注意:这种方式需要确保context能拿到当前User实例,适合在查询解析器中提前将实例绑定到context的场景。
总结
优先选择字段自定义resolve的方式,它最直观、易维护且扩展性强——关联模型的私有字段只需在各自的DjangoObjectType里用相同逻辑处理,完全不用重复定义多套类型、解析器和片段。
内容的提问来源于stack exchange,提问作者ItayAmza
相关产品推荐
相关产品推荐

