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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 02:17:17