多級權限菜單設計級標題欄
我們現在只有數據展示,要進入其他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屬性覆蓋. String backColor: "#000000", //所有節點使用的默認背景色,這個顏色會被節點數據上的backColor屬性覆蓋. String borderColor: "#000000", //邊框顏色。如果不想要可見的邊框,則可以設置showBorder為false。 String nodeIcon: "glyphicon glyphicon-stop", //所有節點的默認圖標 checkedIcon: "glyphicon glyphicon-check", //節點被選中時顯示的圖標 String collapseIcon: "glyphicon glyphicon-minus", //節點被折疊時顯示的圖標 String expandIcon: "glyphicon glyphicon-plus", //節點展開時顯示的圖標 String emptyIcon: "glyphicon", //當節點沒有子節點的時候顯示的圖標 String enableLinks: false, //是否將節點文本呈現為超鏈接。前提是在每個節點基礎上,必須在數據結構中提供href值。 Boolean highlightSearchResults: true, //是否高亮顯示被選中的節點 Boolean levels: 2, //設置整棵樹的層級數 Integer multiSelect: false, //是否可以同時選擇多個節點 Boolean onhoverColor: "#F5F5F5", //光標停在節點上激活的默認背景色 String selectedIcon: "glyphicon glyphicon-stop", //節點被選中時顯示的圖標 String searchResultBackColor: "", //當節點被選中時的背景色 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') # 取每一個字典中的父id if not pid: # 沒有父id(最高權限),就直接加入數據大列表 permission_tree_list.append(per_dic) else: # 有父id就加入父id隊對應的那個的node(一個列表) permission_dic[pid]['nodes'].append(per_dic) # 展開節點 current_path = request.path if 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會幫你做
我們會得到如下頁面: