Djangosimpleui的菜单权限配置,实现无权限不显示菜单
聊聊需求
当我们使用Django+simpleui这个框架的时候,如果想实现当某个用户没有某个菜单的权限时,他无法在界面上看到这个菜单,在不改变源码的情况下是无法实现的,换句话说就是无法直接实现根据权限显示或隐藏菜单。
解决办法-修改simpleui的源代码
需求:Django-simpleui实现根据用户权限显示或者隐藏菜单
- 修改模块:simpletags.py
- 路径:...XXXvenvLibsite-packagessimpleuitemplatetagssimpletags.py(根据你的项目确定路径,一般为虚拟环境)
第一步:注释原有的菜单模块:
# app_list = context.get('app_list')
1. for app in app_list:
1. _models = [
1. {
1. 'name': m.get('name'),
1. 'icon': get_icon(m.get('object_name'), unicode_to_str(m.get('name'))),
1. 'url': m.get('admin_url'),
1. 'addUrl': m.get('add_url'),
1. 'breadcrumbs': [{
1. 'name': app.get('name'),
1. 'icon': get_icon(app.get('app_label'), app.get('name'))
1. }, {
1. 'name': m.get('name'),
1. 'icon': get_icon(m.get('object_name'), unicode_to_str(m.get('name')))
1. }]
1. }
1. 1. for m in app.get('models')
1. ] if app.get('models') else []
1. 1. module = {
1. 'name': app.get('name'),
1. 'icon': get_icon(app.get('app_label'), app.get('name')),
1. 'models': _models
1. }
1. data.append(module)
第二步:读取SIMPLEUI_CONFIG设置合并菜单处理:
...
1. 如果有menu 就读取,没有就调用系统的
key = 'system_keep'
1. if config and 'menus' in config:
1. if config.get(key, None):
1. temp = config.get('menus')
1. for i in temp:
1. # 处理面包屑
1. if 'models' in i:
1. for k in i.get('models'):
1. k['breadcrumbs'] = [{
1. 'name': i.get('name'),
1. 'icon': i.get('icon')
1. }, {
1. 'name': k.get('name'),
1. 'icon': k.get('icon')
1. }]
1. else:
1. i['breadcrumbs'] = [{
1. 'name': i.get('name'),
1. 'icon': i.get('icon')
1. }]
1. data.append(i)
1. else:
1. data = config.get('menus')
1. 修改为
if config and 'menus' in config:
total = config.get('menus')
group_permissions = len(context.request.user.get_group_permissions())
user_permissions = len(context.request.user.get_user_permissions())
if (group_permissions > user_permissions):
user_permissions = context.request.user.get_group_permissions().union(
context.request.user.get_user_permissions())
else:
user_permissions = context.request.user.get_group_permissions().union(
context.request.user.get_user_permissions())
for level_one_menu in total:
1. 与一级菜单codename比对权限
if 'codename' not in level_one_menu or (
True in [(True if level_one_menu['codename'] in u_p else False) for u_p in
user_permissions]) == False:
if context.request.user.is_superuser == False:
continue
1. 处理面包屑
if 'models' in level_one_menu:
del_models = list()
for level_two_menu in level_one_menu.get('models'):
if context.request.user.is_superuser:
pass
elif 'codename' not in level_two_menu.keys():
del_models.append(level_two_menu)
continue
elif ('codename' not in level_one_menu or 'codename' not in level_two_menu
or (level_one_menu['codename'] + '.' + level_two_menu[
'codename'] not in user_permissions)) and
(level_one_menu['codename'] + '.view_' + level_two_menu['codename'] not in user_permissions)
and (
level_one_menu['codename'] + '.add_' + level_two_menu['codename'] not in user_permissions)
and (level_one_menu['codename'] + '.change_' + level_two_menu[
'codename'] not in user_permissions)
and (level_one_menu['codename'] + '.delete_' + level_two_menu[
'codename'] not in user_permissions)
and level_two_menu['codename'] not in user_permissions:
del_models.append(level_two_menu)
continue
level_two_menu['breadcrumbs'] = [{
'name': level_one_menu.get('name'),
'icon': level_one_menu.get('icon')
}, {
'name': level_two_menu.get('name'),
'icon': level_two_menu.get('icon')
}]
for del_m in del_models:
level_one_menu['models'].remove(del_m)
else:
level_one_menu['breadcrumbs'] = [{
'name': level_one_menu.get('name'),
'icon': level_one_menu.get('icon')
}]
if len(level_one_menu['models']) > 0:
data.append(level_one_menu)
else:
data = config.get('menus')
...
1. 获取侧边栏排序, 如果设置了就按照设置的内容排序, 留空则表示默认排序以及全部显示
1. if config.get('menu_display') is not None:
1. display_data = list()
1. for _app in data:
1. if _app['name'] not in config.get('menu_display'):
1. continue
1. _app['_weight'] = config.get('menu_display').index(_app['name'])
1. display_data.append(_app)
1. display_data.sort(key=lambda x: x['_weight'])
1. data = display_data
1. 修改
if config.get('menu_display') is not None:
display_data = list()
for _app in data:
if _app['name'] not in config.get('menu_display'):
continue
1. 处理二级菜单显示权限
if _app.get('menu_display') is not None:
display_model = list()
for _app_m in _app['models']:
if _app_m['name'] not in _app.get('menu_display'):
continue
1. 没有排序逻辑,这里的_weight暂时无效
_app['_weight'] = config.get('menu_display').index(_app['name'])
display_data.append(_app)
else:
display_model = _app['models']
_app['models'] = display_model
_app['_weight'] = config.get('menu_display').index(_app['name'])
display_data.append(_app)
display_data.sort(key=lambda x: x['_weight'])
data = display_data
...
第三步:修改setting.py中的菜单配置。
注意:
- 配置中一级菜单中的codename一般为app名字,二级菜单的codename一般为模型中的类名;
- 只填写一级菜单的codename或不填一级菜单和二级菜单的codename,表示该只允许superuser查看。
...
SIMPLEUI_CONFIG = {
'system_keep': False, # 关闭系统菜单
'dynamic': True, # 设置是否开启动态菜单, 默认为False. 如果开启, 则会在每次用户登陆时动态展示菜单内容
'menus': [
1. 菜单1
{
'app': 'app_article_ad',
'codename' : 'app_article_ad',
'name': '公众号文章',
'icon': 'fas fa-user-shield',
'models': [
{
'name': '文章管理',
'codename':'job_article',
'icon': 'fa fa-user',
'url': 'app_article_ad/job_article/'
},
]
},
1. 菜单2
{
'app': 'app_files',
'codename': 'app_files',
'name': '资源管理',
'icon': 'fas fa-user-shield',
'models': [
{
'name': '文件管理',
'codename': 'file',
'icon': 'fa fa-user',
'url': '/app_files/file_list'
},
]
},
...
修改
if config.get('menu_display') is not None:
display_data = list()
for _app in data:
if _app['name'] not in config.get('menu_display'):
continue
1. 处理二级菜单显示权限
if _app.get('menu_display') is not None:
display_model = list()
for _app_m in _app['models']:
if _app_m['name'] not in _app.get('menu_display'):
continue
1. 没有排序逻辑,这里的_weight暂时无效
_app['_weight'] = config.get('menu_display').index(_app['name'])
display_data.append(_app)
else:
display_model = _app['models']
_app['models'] = display_model
_app['_weight'] = config.get('menu_display').index(_app['name'])
display_data.append(_app)
display_data.sort(key=lambda x: x['_weight'])
data = display_data
效果
管理员界面
普通用户界面