Hiding fields in Flask-Admin depending on logged i

2019-02-16 01:25发布

问题:

I have Users and Roles in my Flask app thanks to Flask-Security.

For some roles I would like to hide certain fields in the forms created by Flask-Admin.

I know about customizing ModelViews with eg. form_create_rules = ('title', 'file') but while instantiating a ModelView there isn't access to the current request so current_user.has_role(USER_ROLE) can't be called.

Is there any other way to achieve this?

回答1:

One way of achieving this is to create multiple view classes and register these view classes against their appropriate roles. See this answer on how to register roles to views. Using view inheritance you can keep common functionality in the "base" class.

For example, suppose we have a user table that implements the Flask-Security mixin and we want the role "admin" to be able to read/set the active field and anyone with the role "user" not to see this field. The class AdminView is defined in the referenced answer.

class AdminUserView(AdminView):

    column_list = ['first_name', 'last_name', 'email', 'roles', 'active']

    form_columns = ['first_name', 'last_name', 'email', 'active', 'roles']

    # Other common functionality here

class UserView(AdminUserView): 

    # Just redefine the columns that can be seen/edited

    column_list = ['first_name', 'last_name', 'email', 'roles']

    form_columns = ['first_name', 'last_name', 'email', 'roles']

# register your views and remember to set a unique endpoint as we are using the same model in multiple views

admin.add_view(AdminUserView(model=User, session=db.session, category="Accounts", name="Users", endpoint="users_admin", roles_accepted=["admin"]))
admin.add_view(UserView(model=User, session=db.session, category="Accounts", name="Users", endpoint="users_user", roles_accepted=["user"]))