Flask-Admin自定义ModelView中current_user类内调用返回None求助
解决Flask-Admin自定义ModelView时类级别代码调用current_user返回None的问题
问题根源
你遇到的AttributeError: 'NoneType' object has no attribute 'permissions'本质是代码执行时机的差异:
- 类定义阶段(比如你写的
if "User w" not in current_user.permissions():)是在Python加载模块时就执行的,这时候Flask的请求上下文还未初始化,current_user指向的是未登录的匿名用户(也就是None),自然无法调用permissions()方法。 - 而
is_accessible这类成员函数是在用户发起请求、访问Admin页面时才会被调用,此时Flask已经创建了请求上下文,current_user已经正确绑定到当前登录用户,所以调用正常。
解决方案
要动态控制can_delete这类权限属性,你需要将判断逻辑移到请求上下文生效时执行的代码块中,最适合的方式是使用@property装饰器,让can_delete成为动态计算的属性:
from flask_admin.contrib.sqla import ModelView from flask_login import current_user class UserDeleteView(ModelView): def is_accessible(self): # 先验证用户是否已认证,再判断权限 if not current_user.is_authenticated: return False return "User" in {i.split()[0] for i in current_user.permissions() } @property def can_delete(self): # 该属性在请求上下文内被访问,current_user已初始化 if not current_user.is_authenticated: return False return "User w" in current_user.permissions() # 其他视图代码保持不变 class PostVarificationView(BaseView): @expose("/") def index(self): return self.render('admin/post_varification.html') class MyAdminIndexView(AdminIndexView): def is_accessible(self): return (current_user.is_authenticated and len(current_user.permissions())!=0) admin = Admin(app,index_view=MyAdminIndexView(),name="Microblog") admin.add_view(UserDeleteView( User, db.session )) admin.add_view(PostVarificationView(name="Post Varification",endpoint="PostVarification"))
为什么这个方案可行?
Flask-Admin的ModelView会在处理用户请求时动态读取can_delete属性,用@property装饰后,每次访问can_delete都会执行对应的逻辑,此时请求上下文已经存在,current_user能正确获取当前登录用户的权限信息。
额外提示
避免在类定义的顶层代码中直接依赖current_user或其他请求上下文相关的对象,这些对象只有在处理用户请求时才会被正确初始化。所有和用户权限、请求状态相关的逻辑,都应该放在视图函数、is_accessible方法或者动态属性中。
内容的提问来源于stack exchange,提问作者Chirag Soni
相关产品推荐
相关产品推荐

