多级权限菜单设计级标题栏
我们现在只有数据展示,要进入其他url还需要手动的输入路径,非常的麻烦,所以我们要设计
一个导航栏以及侧边多级菜单栏,这个展示是通过stark组件的设计的增删改查页面,而 每一个
页面我们都需要有导航栏和侧边的权限菜单栏,所以把这个公共的部分提起到一个网页,让增删改
继承这个页面就可以了.
base.html(这要是自己的样式以及设计盒子让其他网页进行继承)
{% load staticfiles %} <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>CRM</title><link rel="shortcut icon" href="/static /imgs/luffy-study-logo.png"><link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css"/><link rel="stylesheet" href="/static/font-awesome/css/font-awesome.css"/><link rel="stylesheet" href="/static/css/commons.css"/><link rel="stylesheet" href="/static/css/nav.css"/><script src="/static/js/jquery-3.3.1.min.js"></script><style>.pg-body > .left-menu {background-color: #F3F3F3; position: absolute;left: 1px;top: 60px;bottom: 0;width: 220px;overflow: auto;}.pg-body > .right-body {position: absolute;left: 225px;right: 0;top: 60px;bottom: 0;overflow: scroll;border-top: 0;font-size: 13px;min-width: 755px;padding: 20px;}.dropdown-menu {top: 118%;left: -108px;}a:hover{text-decoration: none!important;}</style>{% block css %}{% endblock %}</head> <body><div class="pg-header"><div class="nav"><div class="logo-area left"><a href="#"><img class="logo" src="{% static 'imgs/logo.svg' %}"><span style="font-size: 18px;">CRM </span></a></div><div class="left-menu left"><a class="menu-item">资产管理</a><a class="menu-item">用户信息</a><a class="menu-item">权限管理</a><div class="menu-item"><span>使用说明</span><i class="fa fa-caret-down" aria-hidden="true"></i><div class="more-info"><a href="#" class="more-item">666</a><a href="#" class="more-item">888</a></div></div></div><div class="right-menu right clearfix"><!-- Single button --><div class="btn-group user-info right"><img class="dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" width="50" height="50" class="img-circle" src="{% static 'imgs/default.jpg' %}"><ul class="dropdown-menu small"><li><a href="#" class="more-item">{{request.user.name}}个人信息</a></li><li><a href="/logout/" class="more-item">注销</a></li><li><a href="/home/">修改密码</a></li><li><a href="/home/">更换头像</a></li></ul></div><a class="user-menu right"><i class="fa fa-user" aria-hidden="true"></i><span>{{ request.user }}</span></a><a class="user-menu right">消息<i class="fa fa-commenting-o" aria-hidden="true"></i><span class="badge bg-success">2</span></a><a class="user-menu right">通知<i class="fa fa-envelope-o" aria-hidden="true"></i><span class="badge bg-success">2</span></a><a class="user-menu right">任务<i class="fa fa-bell-o" aria-hidden="true"></i><span class="badge bg-danger">4</span></a></div></div> </div><div class="pg-body">{# 左侧栏 #}<div class="left-menu">{% block side_bar %}{# 自定义标签 #}{% load rbac %}{% get_menu_list request %}{% endblock side_bar %}</div>{# 右侧栏数据体 #}<div class="right-body">{% block content %}{% endblock content %}</div> </div>{% block js %}{% endblock %} </body> </html>
让页面继承了相应的盒子之后,我么就会得到如下样式
那怎么把我们的多级菜单权限展现在右边呢?
这里需要要到一个新的语法(关于自定义模板标签)
建立如下文件夹
rbac.py
from django import template from ..models import Permission register = template.Library()@register.inclusion_tag("rbac/menu.html") def get_menu(request):print("OK...")permission_list = request.session.get("permission_list") #获取权限列表menu_list = []for per in permission_list:if per.get("type") == "menu": #如果是菜单列表加入列表,返回列表和menu.html渲染menu_list.append(per)return {"default_data": default_data}
menu.html
<div id="treeview" class="small"></div><script src="/static/bootstrap-treeview/js/bootstrap-treeview.js"></script> <script type="text/javascript">// API文档参数列表: https://www.cnblogs.com/tangzeqi/p/8021637.html$(function() {var options = {data:{{ default_data|safe }} , //data属性是必须的,是一个对象数组 Array of Objects.color: "", //所有节点使用的默认前景色,这个颜色会被节点数据上的backColor属性覆盖. StringbackColor: "#000000", //所有节点使用的默认背景色,这个颜色会被节点数据上的backColor属性覆盖. StringborderColor: "#000000", //边框颜色。如果不想要可见的边框,则可以设置showBorder为false。 StringnodeIcon: "glyphicon glyphicon-stop", //所有节点的默认图标checkedIcon: "glyphicon glyphicon-check", //节点被选中时显示的图标 StringcollapseIcon: "glyphicon glyphicon-minus", //节点被折叠时显示的图标 StringexpandIcon: "glyphicon glyphicon-plus", //节点展开时显示的图标 StringemptyIcon: "glyphicon", //当节点没有子节点的时候显示的图标 StringenableLinks: false, //是否将节点文本呈现为超链接。前提是在每个节点基础上,必须在数据结构中提供href值。 BooleanhighlightSearchResults: true, //是否高亮显示被选中的节点 Booleanlevels: 2, //设置整棵树的层级数 IntegermultiSelect: false, //是否可以同时选择多个节点 BooleanonhoverColor: "#F5F5F5", //光标停在节点上激活的默认背景色 StringselectedIcon: "glyphicon glyphicon-stop", //节点被选中时显示的图标 StringsearchResultBackColor: "", //当节点被选中时的背景色searchResultColor: "", //当节点被选中时的前景色selectedBackColor: "", //当节点被选中时的背景色selectedColor: "#FFFFFF", //当节点被选中时的前景色showBorder: true, //是否在节点周围显示边框showCheckbox: false, //是否在节点上显示复选框showIcon: true, //是否显示节点图标showTags: false, //是否显示每个节点右侧的标记。前提是这个标记必须在每个节点基础上提供数据结构中的值。uncheckedIcon: "glyphicon glyphicon-unchecked", //未选中的复选框时显示的图标,可以与showCheckbox一起使用};$('#treeview').treeview({color: "#4F4F4F",expandIcon: 'glyphicon glyphicon-chevron-right',collapseIcon: 'glyphicon glyphicon-chevron-down',nodeIcon: 'glyphicon glyphicon-bookmark',enableLinks: true,levels: 1,showIcon:false,selectedBackColor: "",selectedColor: "#333",data: {{ default_data|safe }},});$('#treeview').on('nodeSelected',function(event, data) {console.log(data);})}); </script>
然后在base里面调用这个自定义标签
{# 左侧栏 #}<div class="left-menu">{% block side_bar %}自定义标签{% load rbac %}{% get_menu_list request %}{% endblock side_bar %}</div>
整个流程:
那如何把数据动态的添加到侧边栏呢?我们需要修改代码
rbac.py
@register.inclusion_tag("rbac/menu.html") def get_menu_list(request):permission_list = request.session.get('permission_list')permission_dic = {}for per_dic in permission_list:if per_dic['type'] == 'button':continue # 过滤掉button权限,我们只要菜单权限new_per_dic = {} # 对菜单权限的数据按照treeview的数据结构构建新的字典new_per_dic['text'] = per_dic['title']new_per_dic['href'] = per_dic['url']new_per_dic['nodes'] = []new_per_dic['parent_id'] = per_dic['parent_id']permission_dic[per_dic.get('id')] = new_per_dic # 以自己的权限主键为键,以新构建的字典为值,构造新的字典print('========', permission_dic)permission_tree_list = [] # 整个数据大列表for per_id, per_dic in permission_dic.items():pid = per_dic.get('parent_id') # 取每一个字典中的父idif not pid: # 没有父id(最高权限),就直接加入数据大列表 permission_tree_list.append(per_dic)else: # 有父id就加入父id队对应的那个的node(一个列表)permission_dic[pid]['nodes'].append(per_dic)# 展开节点current_path = request.pathif current_path == per_dic.get('href'):pid = per_dic.get('parent_id')per_dic['emptyIcon']=''while pid:permission_dic[pid]['state'] = {'expanded': True}pid = permission_dic[pid]['parent_id']return {'permission_tree_list': json.dumps(permission_tree_list)} #前端不需要反序列化,bootstrap treeview会帮你做
我们会得到如下页面: