Django-guardian中用户继承组权限但has_perm(obj)返回False的问题
Django Guardian 权限检查问题解决
问题原因
你给staff组分配的是全局权限(未指定对象),但调用user.has_perm("view_income", income)时,django-guardian默认仅检查对象级权限(包括用户直接绑定的对象权限、组绑定的对象权限),不会自动关联全局组权限,所以返回False。
快捷解决方案:自定义权限检查函数
如果你想一次性判断用户是否拥有指定对象的权限(覆盖全局权限、全局组权限、对象级用户/组权限),可以写一个通用工具函数:
from guardian.shortcuts import get_perms, get_group_perms def has_any_permission(user, perm_code, obj=None): # 1. 检查用户全局权限或所属组的全局权限 if user.has_perm(perm_code): return True # 2. 若传入对象,检查对象级权限 if obj is not None: # 检查用户直接绑定的对象权限 if perm_code in get_perms(user, obj): return True # 检查用户所属组绑定的对象权限 for group in user.groups.all(): if perm_code in get_group_perms(group, obj): return True return False
修改测试用例
将测试中的has_perm替换为自定义函数即可:
def test_permissions(self): income = baker.make("clients.Income", client=self.user_a) self.assertTrue(self.user_a.has_perm("view_income", income)) # 使用自定义函数完成一次性检查 self.assertTrue(has_any_permission(self.user_c, "view_income", income))
另一种极简写法(适合单次调用)
如果不想写函数,也可以直接用逻辑或覆盖所有情况:
# 检查全局权限 + 对象级权限 has_perm = self.user_c.has_perm("view_income") or self.user_c.has_perm("view_income", income) self.assertTrue(has_perm)
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

