Flask-Admin 不同的形式和 column_list 不同的角色
Flask-Admin different forms and column_list for different roles
跟进这个问题我不明白如何实现基于角色的视图,尤其是关于表单和column_lists。
假设我希望 MyModelView
在用户是普通用户或超级用户时显示不同的列。
在 MyModelView
中覆盖 is_accessible
根本没有效果
from flask_security import Security, SQLAlchemyUserDatastore, current_user
class MyModelView(SafeModelView):
# ...
def is_accessible(self):
if current_user.has_role('superuser'):
self.column_list = superuser_colum_list
self.form_columns = superuser_form_columns
else:
self.column_list = user_colum_list
self.form_columns = user_form_columns
return super(MyModelView, self).is_accessible()
# Has same effect as
def is_accessible(self):
return super(MyModelView, self).is_accessible()
和定义条件 class 属性也不起作用,因为 current_user
未定义(NoneType
根据 AttributeError on current_user.is_authenticated() 的错误)。在ModelView的__init__
中做同样的事情是等价的,current_user
仍然没有定义
class MyModelView(SafeModelView):
#[stuff]
if current_user.has_role('superuser'):
column_list = superuser_colum_list
form_columns = superuser_form_columns
else:
column_list = user_colum_list
form_columns = user_form_columns
#[other stuff]
仅供参考,SafeModelView
可以是从前面提到的问题中的 dgBaseView
继承的任何 class。
我通常定义视图class属性如column_list
作为properties。它允许您向它们添加一些动态逻辑:
from flask import has_app_context
from flask_security import current_user
class MyModelView(SafeModelView):
@property
def column_list(self):
if has_app_context() and current_user.has_role('superuser'):
return superuser_column_list
return user_column_list
@property
def _list_columns(self):
return self.get_list_columns()
@_list_columns.setter
def _list_columns(self, value):
pass
使用这种方法的问题(以及为什么您在 is_accessible
函数中重新分配 column_list
值没有效果)是许多视图属性在应用程序启动时缓存并存储在私有属性中。例如 column_list
缓存在 _list_columns
属性中,因此您也需要重新定义它。您可以在 flask_admin.model.base.BaseModelView._refresh_cache 方法中查看此缓存的工作原理。
此处需要 Flask has_app_context
方法,因为当您的 current_user
变量还没有有意义的值时,第一个 column_list
读取发生在应用程序启动时。
同样可以用form_columns
属性来完成。属性将如下所示:
@property
def form_columns(self):
if has_app_context() and current_user.has_role('superuser'):
return superuser_form_columns
return user_form_columns
@property
def _create_form_class(self):
return self.get_create_form()
@_create_form_class.setter
def _create_form_class(self, value)
pass
@property
def _edit_form_class(self):
return self.get_edit_form()
@_edit_form_class.setter
def _edit_form_class(self, value):
pass
跟进这个问题
假设我希望 MyModelView
在用户是普通用户或超级用户时显示不同的列。
在 MyModelView
中覆盖 is_accessible
根本没有效果
from flask_security import Security, SQLAlchemyUserDatastore, current_user
class MyModelView(SafeModelView):
# ...
def is_accessible(self):
if current_user.has_role('superuser'):
self.column_list = superuser_colum_list
self.form_columns = superuser_form_columns
else:
self.column_list = user_colum_list
self.form_columns = user_form_columns
return super(MyModelView, self).is_accessible()
# Has same effect as
def is_accessible(self):
return super(MyModelView, self).is_accessible()
和定义条件 class 属性也不起作用,因为 current_user
未定义(NoneType
根据 AttributeError on current_user.is_authenticated() 的错误)。在ModelView的__init__
中做同样的事情是等价的,current_user
仍然没有定义
class MyModelView(SafeModelView):
#[stuff]
if current_user.has_role('superuser'):
column_list = superuser_colum_list
form_columns = superuser_form_columns
else:
column_list = user_colum_list
form_columns = user_form_columns
#[other stuff]
仅供参考,SafeModelView
可以是从前面提到的问题中的 dgBaseView
继承的任何 class。
我通常定义视图class属性如column_list
作为properties。它允许您向它们添加一些动态逻辑:
from flask import has_app_context
from flask_security import current_user
class MyModelView(SafeModelView):
@property
def column_list(self):
if has_app_context() and current_user.has_role('superuser'):
return superuser_column_list
return user_column_list
@property
def _list_columns(self):
return self.get_list_columns()
@_list_columns.setter
def _list_columns(self, value):
pass
使用这种方法的问题(以及为什么您在 is_accessible
函数中重新分配 column_list
值没有效果)是许多视图属性在应用程序启动时缓存并存储在私有属性中。例如 column_list
缓存在 _list_columns
属性中,因此您也需要重新定义它。您可以在 flask_admin.model.base.BaseModelView._refresh_cache 方法中查看此缓存的工作原理。
此处需要 Flask has_app_context
方法,因为当您的 current_user
变量还没有有意义的值时,第一个 column_list
读取发生在应用程序启动时。
同样可以用form_columns
属性来完成。属性将如下所示:
@property
def form_columns(self):
if has_app_context() and current_user.has_role('superuser'):
return superuser_form_columns
return user_form_columns
@property
def _create_form_class(self):
return self.get_create_form()
@_create_form_class.setter
def _create_form_class(self, value)
pass
@property
def _edit_form_class(self):
return self.get_edit_form()
@_edit_form_class.setter
def _edit_form_class(self, value):
pass