Django中基于模型权限限制视图访问失效问题排查
解决Django权限校验
has_perm()返回False的问题 首先,你遇到的最直接问题是调用has_perm()时的传参错误,这也是调试中返回False的核心原因。让我们一步步拆解并解决问题:
1. 修正has_perm()的传参格式
Django的User.has_perm()方法要求传入字符串格式的权限标识符,格式为{app_label}.{codename},而不是直接传入Permission对象。
你调试时的错误代码:
user.has_perm(permission_view_user) # 错误:传入了Permission对象
应该修改为(替换your_app为你的Member模型所在的app名称,比如模型在library app下就是library.view_member):
user.has_perm('your_app.view_member') # 正确:传入字符串格式的权限标识
2. 测试用例中刷新用户实例
在测试里给用户添加权限后,Django会把用户对象缓存到内存中,你需要刷新实例才能看到权限的更新。可以通过两种方式实现:
- 调用
refresh_from_db()方法重新从数据库加载数据:test_user0.user_permissions.add(permission_view_user) test_user0.save() test_user0.refresh_from_db() # 新增:刷新用户实例 print(test_user0.has_perm('your_app.view_member')) # 现在会返回True - 或者重新从数据库获取用户对象:
test_user0.user_permissions.add(permission_view_user) test_user0.save() user = User.objects.get(pk=test_user0.pk) # 重新获取用户 print(user.has_perm('your_app.view_member')) # 返回True
3. 验证视图中的权限校验逻辑
确保你视图里的权限校验使用了正确的字符串格式:
# 替换成你的app名称,比如library.view_member if request.user.has_perm('your_app.view_member'): context['user_list'] = get_user(q)
4. 额外排查点
- 确认权限的
app_label正确:检查Permission.objects.get(codename='view_member').app_label,确保它和你的Member模型所在的app名称一致。比如模型在libraryapp下,app_label必须是library。 - 检查组权限:如果用户是通过用户组获得的权限,要确认组确实被分配了
view_member权限,并且用户属于该组。 - 确认权限存在:确保
view_member权限是Django自动生成的模型权限(默认格式为view_{modelname}),或者是你自定义的权限已正确注册。
调整完这些步骤后,你的权限校验应该就能正常工作了,测试用例里的断言也会通过。
内容的提问来源于stack exchange,提问作者Moanos
相关产品推荐
相关产品推荐

