为什么管理网站不关心我的自定义用户的权限?

时间:2017-02-10 14:36:16

标签: python django

我创建了一个Django(1.10.3)项目,其中包含一个继承自AbstractBaseUser的自定义用户模型。在开发这个东西的几个星期后,我发现我需要为管理员用户提供更细粒度的权限,因此我使用PermissionsMixin扩展了我的用户模型,生成并应用了迁移,并更新了我的ModelAdmin

要尝试一下,我使用我的超级用户登录管理员,并创建了一个手动添加了所有权限的新用户。当我使用该新用户登录时,我受到了很好的"您没有权限编辑任何内容"

所以我去了shell,检查了用户的权限,他们就在那里。

>>> u = User.objects.get(username='new_user')
>>> u.get_all_permissions()
{'admin.add_logentry', ...}

然而,

>>> u.has_perm('admin.add_logentry')
False

现在,如果用户不是活跃的超级用户,has_perm的作用就是调用它:

def _user_has_perm(user, perm, obj):
    for backend in auth.get_backends():
        if not hasattr(backend, 'has_perm'):
            continue
        try:
            if backend.has_perm(user, perm, obj):
                return True
        except PermissionDenied:
            return False
    return False

但是,

>>> from django.contrib.auth import get_backends
>>> backend = get_backends()[0]  # django.contrib.auth.backends.ModelBackend
>>> backend.has_perm(u, 'admin.add_logentry')
True

所以,

为什么user.has_perm(perm)backend.has_perm(user, perm)会返回不同的值? 最后,如何在这种情况下让权限系统正常工作?

1 个答案:

答案 0 :(得分:1)

我应该对这个问题的实际答案感到羞耻。至少我希望从中吸取教训。也许我可以按照“总是先检查你自己的实现”的方式添加一些东西来修复启发式错误。

这两种方法显然不可能返回不同的东西,这使我检查我是否真的在调用它们。事实证明,我完全忘记了我自己的has_perm实现,我为了让用户模型与管理员兼容而心不在焉。 当然,此实现仅检查超级用户状态。

我认为奥卡姆的家伙正在做点什么。