Django非管理员用户无法继承组权限问题求助
问题分析与解决建议
先把你的Django Shell会话整理成更清晰的格式:
>>> from django.contrib.auth.models import User, Group >>> g = Group.objects.all() >>> g <QuerySet [<Group: Tester>, <Group: Testmanager>]> >>> g[1].permissions.all() <QuerySet [..., <Permission: testman | test plan step | Can add test plan step>, <Permission: testman | test plan step | Can change test plan step>, <Permission: testman | test plan step | Can delete test plan step>, <Permission: testman | test plan step | Can view test plan step>, ...]> >>> g[1].user_set.all() <QuerySet [<User: somedude>, <User: testma>]> >>> u = User.objects.all() >>> u <QuerySet [<User: somedude>, <User: test>, <User: testma>]> >>> u[0].has_perm('testman.create_testplanstep') True >>> u[2].has_perm('testman.create_testplanstep') False
根据你描述的情况,testma属于拥有TestPlanStep全部权限的Testmanager组,但has_perm返回False,最可能的问题出在权限编码名称错误,下面分点说明排查方向:
1. 权限编码名称使用错误(最核心原因)
Django为模型自动生成的权限编码格式是:app_label.action_modelname,其中action固定是add、change、delete、view,而不是你用的create。
从你的Shell输出能看到,权限显示为Can add test plan step,对应的正确权限编码应该是:
'testman.add_testplanstep' # 注意是add_而非create_
你当前调用的testman.create_testplanstep是不存在的权限!而somedude作为超级管理员,has_perm会直接返回True(超级管理员默认拥有所有权限,不管权限是否实际存在),这就是为什么两者结果不同。
你可以先测试正确的权限编码:
>>> u[2].has_perm('testman.add_testplanstep')
如果返回True,那就是权限名称的问题。
2. 确认用户确实属于目标组
虽然你通过g[1].user_set.all()看到了testma,但为了避免索引错误(比如u[2]是不是真的是testma),可以直接查询该用户的组:
>>> testma = User.objects.get(username='testma') >>> testma.groups.all() # 检查结果是否包含<Group: Testmanager>
3. 清除Django权限缓存
Django会缓存用户的权限信息,如果你是最近修改了组权限或用户组归属,可能需要清除缓存,或者让用户重新登录(权限缓存会在登录时刷新)。
也可以在Shell里强制刷新用户权限缓存:
>>> testma = User.objects.get(username='testma') # 重新获取用户对象,刷新缓存 >>> testma.has_perm('testman.add_testplanstep')
4. 确认组的权限确实正确关联
虽然Shell输出显示组有相关权限,但可以精准查询确认:
>>> from django.contrib.auth.models import Permission >>> add_perm = Permission.objects.get(codename='add_testplanstep', content_type__app_label='testman') >>> g[1].permissions.filter(pk=add_perm.pk).exists() # 返回True则说明组确实拥有该权限
内容的提问来源于stack exchange,提问作者uwain12345
相关产品推荐
相关产品推荐

