Flask-AppBuilder
Flask-AppBuilder copied to clipboard
How to use @has_access in custom widget template html file.
I customize my own ListWidget with a template file where I add an action button like below.
{% block list_header %}
{{ super() }}
<a href="url_for('doaction')" class="btn btn-sm btn-primary">
<i class="fa fa-rocket"></i>
</a>
{% endblock %}
Then I add @expose in the view.py like below.
@expose("/action", methods=['GET'])
@has_access
def doaction(self):
My questions is how to control the action button display based on user's permission. Thanks.
This might not be best way, but it has worked for me:
in template I have
{% if 'Coordinator' in user_role_list or 'Admin' in user_role_list %}
<div class="btn-group" role="button group" aria-label="show and edit">
in views.py
@expose("/example", methods=['GET'])
def example_view(self):
user_role_list = get_user_role_list()
return self.render_template(
template[show],
user_role_list=user_role_list
)
and
def get_user_role_list():
"""
Returns:
list -- of str of names of Roles of g.user, empty list if not logged in
:rtype: list
"""
if not g.user.is_anonymous:
return [str(r) for r in g.user.roles]
return []
One problem with this methodology is that the user permission role names are hard-coded in source, but it has been ok for me
@soundmaking Thanks for your help. It is work. For me, there are my codes. (1) models.py
class MyUser(User):
__tablename__ = "ab_user"
def is_admin(self):
if 'Admin' in [r.name for r in self.roles] :
return True
else :
return False
(2)widget template html
{% block list_header %}
{{ super() }}
{% set user_is_admin = g.user.is_admin() %}
{% if user_is_admin %}
<a href="url_for('doaction')" class="btn btn-sm btn-primary">
<i class="fa fa-rocket"></i>
</a>
{% endif %}
{% endblock %}
One problem is that I can only check user's roles. In fact, I want to check user's specifc permission. I don't know how to list permissions.
Good idea to define the function in your User class - I would do that if/when I were starting again!
you can access list of permissions on each role with role.permissions
so maybe something along the line of this untested code:
class MyUser(User):
# . . .
def has_permission(self, permission_name)
for role in self.roles:
if permission_name in [p.name for p in role.permissions]:
return True
return False
There is an error about if permission_name in [p.name for p in role.permissions]: , because p has no attribution name. I change them to below. But it still can not work. I don't know why.
def has_permission(self, permission_name):
for role in self.roles:
if permission_name in role.permissions :
return True
return False
I checked the original code about permission_view. And changed the codes into below. They can work.
def has_permission(self, permission_name, view_menu_name):
for role in self.roles:
for ps in role.permissions:
if (ps.permission.name == permission_name and ps.view_menu.name == view_menu_name):
return True
return False