用户有没有某个权限,Django 怎么算?为什么刚给用户加了权限,has_perm 还是 False?对象级权限支持吗?这篇逐条验证。
['add_article', 'change_article', 'delete_article', 'publish_article', 'view_article']
权限行由 post_migrate 信号创建,所以新加的模型要迁移之后才有权限行。
没有任何权限: False 直接授予 add_article 之后(还是同一个 user 对象): False ← 权限缓存! 重新从数据库取用户: True 加入组后(新取的用户,还没有查过权限): True 超级用户 has_perm(任意字符串): True 超级用户但 is_active=False: False has_perm 需要 "app_label.codename" 格式,只写 codename: False
需要 app_label.codename 全名。组的权限和直接授予的权限取并集。
第一次 has_perm:查询 2
SELECT "django_content_type"."app_label" AS "content_type__app_label", "auth_permission"."codename"
SELECT "django_content_type"."app_label" AS "content_type__app_label", "auth_permission"."codename"
之后再查其它权限:查询 0 (_perm_cache / _user_perm_cache / _group_perm_cache 在对象上)
缓存属性: ['_group_perm_cache', '_perm_cache', '_user_perm_cache']在 request.user 上调用 has_perm 时,缓存存在这个对象上,随请求结束消失,所以「每个请求最多查两次库」。但在测试或脚本里长期持有同一个 user 对象时容易踩坑。
has_perm("lab.change_article") = True has_perm("lab.change_article", obj) = False
超级用户带 obj: TrueDjango 提供了 obj 参数的接口,但默认的 ModelBackend 不实现。