菜单权限
左侧栏展示用户拥有的权限
1, 重构stark组件 ,加上title和左侧栏
创建base.html,静态文件
{%block css%}
盒子,继承的页面要继承这个模板,他有自己的CSS,为了扩充css用的
{%endblock%}
2,更改编辑和删除按钮的图标
图标网址: font awespme 这个网站的图标比较丰富
copy到自己的stark-->sites.py , 也要引这个插件才能用
list_view.html 要继承 base.html
两个盒子
3, 做添加页面
add_view.html 继承 base.html
编辑和删除页面 同上操作 .
4, base.html---> {% side_bar %} 左边栏
构建左侧权限标签(动态构建, "路径","文本")
注意!!
动态参数的不能做菜单权限,能做菜单权限的只有查看
查看客户和查看订单注意两个方面: 1, 文本要展示出来, 2,过滤出来真正的菜单权限,
之前在permissions.py录入的数据,有url,没有title,就没办法做文本了,不要用这个列表,用字典.
更改:
在去base.html
再去登录页面前 要去改 middlewares.py中间件,
登录页面后,页面是这样的
出现了8个,但我们只要两个; 进行过滤,
定义: 查看订单和查看客户为菜单权限,其他为按钮权限
重新设计Permission表字段
数据迁移>>>>> 查看更改数据库
再回到 permissions.py 进行 筛选 , 添加 :
再去stark组件 >>> sites.py>>> list_view视图中,进行判断筛选
然后在 base.html 中 side_bar 循环 menu_list :
重新进行登录和查看
\
现在出现了一个恶心的事,刚刚的操作 动了stark >>> sites 的源码.
后果是 菜单权限 只有在 list_view 视图中才会显示,每个视图都写一份也能实现, 但代码重复,也不能动源码.
这个用自定义标签过滤器方法 :
在 rbac >>> 建一个templatetags >>> rbac.py (写自定义模板)
在 rbac >>> 建一个templates >>> menu.html (menu 模板)
构建自定义I标签:
以上在 list_view 视图中 写的函数 写在 templatetags >>> rbac.py 中 ,因为这是跟权限相关的
语法 : @register.inclusion_tag() 括号里放 样式,传给谁用的
流程 : templatetags >>> rbac.py(构建数据) 传给 templates >>> menu.html(渲染出来两个a 'or' p标签)
最终到 base.html *这样数据 , 样式 就都在rbac 中了 , 耦合性好
最后 ,按照加载应用从上到下的顺序,为了避免 menu.html 被上边的应用重复后覆盖,在
templates >>> 建 rbac的包, 在把 menu.html 放进去.
templatetags >>> 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_list.append(per) default_data=[ { "text": '信息管理', "href": '', "tags": ['2'], "nodes": [ { "text": '客户管理', "href": '', "tags": ['1'], "nodes": [ { "text": '查看客户', "href": '/stark/app01/customer/', "tags": ['0'] }, ] }, { "text": '订单管理', "href": '', "tags": ['1'], "nodes": [ { "text": '查看订单', "href": '/stark/app01/order/', "tags": ['0'] }, ] }, ] }, { "text": '权限管理', "href": '', "tags": ['0'] }, ] return {"default_data": default_data}
templates >>>rbac>>>> 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 = { #safe:不加这个浏览器会转义 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.html 获取到数据
<div class="pg-body"> <div class="left-menu"> {% block side_bar %} {% load rbac %} {% get_menu request %} {% endblock side_bar %} </div> <div class="right-body"> {% block content %} {% endblock content %} </div> </div>
补充 :
多级菜单 展示
一级菜菜单没有URL 二级也没有 ,最后一级有URL, 也就是它的父级都没有URL
权限与权限之间建立父子关系 , 自关联的东东 , 一个父权限有多个子权限.一个子权限只能有一个父权限
在权限的 model 中建立字段
在加一个 blank=True 默认为空 , 数 据 迁 移
默认为True,在页面就可以写URL就可以不写
在 rbac >>> stark.py 中加展示
登录后 进入 permissions 加点权限
查看订单 改成 订单管理 下
下边构建树形数据结构 ,
templatetags >>> rbac.py(构建数据) 里
是一个列表,一个权限放在一个字典中
treeview5 :>> 是标签div的名字,找到这个标签
text : 标签构建的文本
href : 路径
tags : 有多少的子节点 ,就是就几个儿子
nodes : 是它下边的儿子,下边几个字典就几个儿子
menu.html 就不要自己写了,用插件写 , 引 static 组件,
menu.html插件需要的数据,rbac提供数据( menu插件要求的 default_data 格式是:
( 一个列表套一个字典,字典里代表有权限的URL tags, nodes 里套几个儿子 )