Flask-Admin:根据请求形成脚手架
Flask-Admin: Form scaffolding per-request
场景
我正在使用 Flask-Admin 创建一个 CRUD 界面。我正在使用 flask.session
来确定当前登录用户的角色。基于这个角色,我想根据请求构建不同的脚手架 forms/views。
代码
index.py
from institution import InstitutionView
app = flask.Flask(...)
admin = flask_admin.Admin(...)
# artificial user data
user_dict = {
...
'role' : 'Teacher'
}
# pass user data to institution view
institutionView = InstitutionView(..., user=user_dict)
admin.add_view(institutionView)
institution.py
class InstitutionView(ModelView):
...
def scaffold_list_columns(self):
# generate columns dynamically
if self._user['admin_role'] == 'Teacher':
return ('name', 'c_date', 'e_date')
return ('name', 'foo', 'bar', 'c_date', 'e_date')
def scaffold_form(self):
# generate fields dynamically
if self._user['admin_role'] == 'Teacher':
...
问题
到目前为止,我一直在人为地将用户数据注入 InstitutionView
构造函数。现在我想从 flask.session
中提取数据,这是一个问题。 脚手架需要在请求上下文中发生,但目前发生在应用程序初始化时。
我是 Flask 的新手,所以很可能我做错了。
更新 2015.8.20
一种可能性是覆盖在每次请求时调用的 flask_admin.base.BaseView.render()
。但是,我需要在 render()
中重现 flask-admin 的表单脚手架逻辑,这远非微不足道(或干净)。
解决方法是覆盖两个方法:
flask_admin.model.base.BaseView._handle_view()
flask_admin.model.base.BaseModelView._refresh_cache()
代码:
class InstitutionView(ModelView):
...
# _handle_view called every request
def _handle_view(self, name, **kwargs):
if not flask_login.current_user.is_authenticated():
return self.inaccessible_callback(name, **kwargs)
# re-scaffold views every request
self._refresh_cache()
return super(InstitutionView, self)._handle_view(name, **kwargs)
# _refresh_cache called once when view is added to admin interface
def _refresh_cache(self):
# do not _refresh_cache outside of a request context
if not flask_login.current_user:
# init members with empty tuples to avoid instantiation error
self._list_columns = ()
return
super(InstitutionView, self)._refresh_cache()
场景
我正在使用 Flask-Admin 创建一个 CRUD 界面。我正在使用 flask.session
来确定当前登录用户的角色。基于这个角色,我想根据请求构建不同的脚手架 forms/views。
代码
index.py
from institution import InstitutionView
app = flask.Flask(...)
admin = flask_admin.Admin(...)
# artificial user data
user_dict = {
...
'role' : 'Teacher'
}
# pass user data to institution view
institutionView = InstitutionView(..., user=user_dict)
admin.add_view(institutionView)
institution.py
class InstitutionView(ModelView):
...
def scaffold_list_columns(self):
# generate columns dynamically
if self._user['admin_role'] == 'Teacher':
return ('name', 'c_date', 'e_date')
return ('name', 'foo', 'bar', 'c_date', 'e_date')
def scaffold_form(self):
# generate fields dynamically
if self._user['admin_role'] == 'Teacher':
...
问题
到目前为止,我一直在人为地将用户数据注入 InstitutionView
构造函数。现在我想从 flask.session
中提取数据,这是一个问题。 脚手架需要在请求上下文中发生,但目前发生在应用程序初始化时。
我是 Flask 的新手,所以很可能我做错了。
更新 2015.8.20
一种可能性是覆盖在每次请求时调用的 flask_admin.base.BaseView.render()
。但是,我需要在 render()
中重现 flask-admin 的表单脚手架逻辑,这远非微不足道(或干净)。
解决方法是覆盖两个方法:
flask_admin.model.base.BaseView._handle_view()
flask_admin.model.base.BaseModelView._refresh_cache()
代码:
class InstitutionView(ModelView):
...
# _handle_view called every request
def _handle_view(self, name, **kwargs):
if not flask_login.current_user.is_authenticated():
return self.inaccessible_callback(name, **kwargs)
# re-scaffold views every request
self._refresh_cache()
return super(InstitutionView, self)._handle_view(name, **kwargs)
# _refresh_cache called once when view is added to admin interface
def _refresh_cache(self):
# do not _refresh_cache outside of a request context
if not flask_login.current_user:
# init members with empty tuples to avoid instantiation error
self._list_columns = ()
return
super(InstitutionView, self)._refresh_cache()