如何扩展Django login_required装饰器校验自定义用户模型的布尔字段权限
可行解决方案
原有代码问题排查
- 语法错误:
userAuth = request.user.isAuthenticated:末尾多写冒号,且Django的用户认证状态属性为全小写的is_authenticated(1.10+版本为属性无需加括号调用) - 语法错误:权限不足的提示字符串跨行未做拼接处理,直接触发语法报错
- 逻辑隐患:自定义布尔字段配置了
null=True,未显式判断值为True,空值None会被判定为假,可能出现不符合预期的校验结果 - 规范问题:未使用
functools.wraps保留原视图函数元信息,可能导致路由、缓存等依赖函数属性的功能异常 - 拼写错误:Django消息框架的调用名称为
messages,你代码里写的message少了末尾的s
修复后的单角色装饰器代码
from functools import wraps from django.shortcuts import redirect from django.contrib import messages def vendor_login_required(function): @wraps(function) def wrapper(request, *args, **kwargs): # 先校验是否登录 if not request.user.is_authenticated: messages.success(request, "Please login") return redirect('/login') # 再校验角色权限 if not request.user.is_estate_vendor is True: messages.error(request, "You are not authorized to be here, login as a vendor to continue") return redirect('/login') # 校验通过执行视图 return function(request, *args, **kwargs) return wrapper
通用可复用角色装饰器(推荐,适配所有用户类型)
不用为每类角色单独写装饰器,通过传参指定校验的字段即可:
from functools import wraps from django.shortcuts import redirect from django.contrib import messages def role_required(role_field: str): def decorator(function): @wraps(function) def wrapper(request, *args, **kwargs): if not request.user.is_authenticated: messages.success(request, "请先登录") return redirect('/login') # 动态获取用户的角色字段值 if not getattr(request.user, role_field, False) is True: messages.error(request, "您无权限访问该页面,请切换对应账号登录") return redirect('/login') return function(request, *args, **kwargs) return wrapper return decorator
使用示例
# 校验物业供应商角色 @role_required('is_estate_vendor') def vendor_dashboard(request): # 视图逻辑 pass # 校验物业保安角色 @role_required('is_estate_security') def security_task_list(request): # 视图逻辑 pass
内容的提问来源于stack exchange,提问作者Ihon Oseghale
相关产品推荐
相关产品推荐

