crm 动态一级二级菜单
之前代码菜单是写是的
如何 让他 动态 生成了 首先 添加 2个字段
admin.py 更改 显示
from django.contrib import admin
from rbac import models # Register your models here. class PermissionAdmin(admin.ModelAdmin):
list_display = ['url', 'title','is_menu','icon']#列表显示
list_editable = ['title','is_menu','icon']#可编辑
admin.site.register(models.Permission, PermissionAdmin)
admin.site.register(models.Role)
admin.site.register(models.User)
然后进入 admin 把设为 一级菜单的 图标设置上去
auth.py 进行 mode筛选
def login(request):
if request.method == 'POST':
# 获取用户名和密码
user = request.POST.get('user')
pwd = request.POST.get('pwd')
# 去数剧库进行筛选
obj = models.User.objects.filter(name=user, pwd=pwd).first()
if not obj:
return render(request, 'login.html')
permission_query = obj.roles.filter(permissions__url__isnull=False).values('permissions__url',
'permissions__title','permissions__is_menu','permissions__icon').distinct()
#通过查询到的用户的obj反查角色表,values 正向查询当前用户的权限表的url信息 title permission_list=[]#存放权限信息
menu_list=[]#存放菜单信息
for item in permission_query:
permission_list.append({'url':item['permissions__url']})
if item.get('permissions__is_menu'):
menu_list.append({'url':item['permissions__url'],'icon':item['permissions__icon'],'title':item['permissions__title']}) # print('1111',permission_query) # <QuerySet [{'permissions__url': '/index/', 'permissions__title': '首页'}]>
#将权限信息写入到session
request.session[settings.PERMISSION_SESSION_KEY]=permission_list
#将菜单 信息 写入session
request.session[settings.MENU_SESSION_KEY]=menu_list
request.session['is_login'] = True
return redirect(reverse('index'))
return render(request, 'login.html')
settings.py中定义
# 白名单
WHITE_LIST = [
r'^/login/$',
r'^/reg/$',
r'^/admin/.*',
]
# 免认证的地址 需要登录 不行权限校验
NO_PERMISSION_LIST = [
'/index/'
]
#权限信息url key
PERMISSION_SESSION_KEY='permissions'
#存放菜单信息
MENU_SESSION_KEY='menus'
更改一下 rbacapp中 更改 中间件中 middlewares/rbac.py 相应的值
# 获取当前用户的权限
permission_list = request.session[settings.PERMISSION_SESSION_KEY]
print(permission_list)
# 权限的校验
for i in permission_list:
if re.match('^{}$'.format(i['url']), url):
return
# 没匹配成功 没有权限
return HttpResponse('没有访问的权限')
layout.html中 跟改显示 这样虽然成功了 但是还是写死了menus
<div class="static-menu">
{# <a href="/customer/list/" class="active">#}
{# <span class="icon-wrap"><i class="fa fa-connectdevelop"></i></span> 客户管理</a>#}
{# <a href="/payment/list/">#}
{# <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> 账单管理</a>#}
{% for item in request.session.menus %}
<a href="{{ item.url }}">
<span class="icon-wrap"><i class="fa fa-code-fork"></i></span> {{ item.title }}</a>
{% endfor %}
</div>
如何解决?
自定义 inclusion_tag
创建 templatetags目录 rbac.py
from django import template
from django.conf import settings
register=template.Library()
import re
@register.inclusion_tag('menu.html')
def menu(request):
menu_list=request.session.get(settings.MENU_SESSION_KEY)
for item in menu_list:
url=item['url']
if re.match('^{}$'.format(url),request.path_info):
item['class']='active'
return {'menu_list':menu_list}
menu.html
<div class="static-menu">
{% for item in menu_list%}
<a href="{{ item.url }}" class="{{ item.class }}">
<span class="icon-wrap"><i class="fa fa-code-fork"></i></span> {{ item.title }}</a>
{% endfor %}
</div>
为了 下次 直接调用rbac 整合
把之前的判断 web views中的auth.py中的 查询写入session部分 移动到rbac/server/init_permission.py
from django.conf import settings
def init_permission(request, obj):
permission_query = obj.roles.filter(permissions__url__isnull=False).values('permissions__url',
'permissions__title',
'permissions__is_menu',
'permissions__icon').distinct()
permission_list = [] # 存放权限
menu_list = [] # 存放菜单信息
for item in permission_query:
permission_list.append({'url': item['permissions__url']})
if item.get('permissions__is_menu'):
menu_list.append({'url': item['permissions__url'], 'icon': item['permissions__icon'],
'title': item['permissions__title']})
# 将权限写入session
request.session[settings.PERMISSION_SESSION_KEY] = permission_list
# 将菜单写入 session
request.session[settings.MENU_SESSION_KEY] = menu_list
request.session['is_login'] = True
if not obj:
return redirect(reverse('login'))
# 认证成功 进行权限信息初始化(权限、菜单)
init_permission(request, obj)
return redirect(reverse('index'))
把 web下的 templatetags 移动到rbac app下
自定义标签inclusion
把menu.html 移动到新建templates/rbac/中
把 css部分 移动到 static/css/menu.css
二级菜单调用自动生成
更改modes中的表字段 添加 menu表
进入 admin 进行 权限 划分
更改 server permission.py
# 权限的列表
permission_list = [] # 菜单的字典
menu_dict ={} for i in permission_query:
# 把权限的信息放入permission_list
permission_list.append({'url': i['permissions__url']}) menu_id = i.get('permissions__menu_id') if not menu_id:
continue menu_dict.setdefault(menu_id, {
'title': i['permissions__menu__title'],
'icon': i['permissions__menu__icon'],
'children': [ ]
}) menu_dict[menu_id]['children'].append({'title': i['permissions__title'], 'url': i['permissions__url']})
from django import template
from django.conf import settings
import re register = template.Library() @register.inclusion_tag('rbac/menu.html')
def menu(request):
menu_dict = request.session[settings.MENU_SESSION_KEY] return {'menu_list': menu_dict.values()}
rbac/static/rbac/css/menu.css
.left-menu .menu-body .static-menu { } .left-menu .menu-body .static-menu .icon-wrap {
width: 20px;
display: inline-block;
text-align: center;
} .left-menu .menu-body .static-menu a {
text-decoration: none;
padding: 8px 15px;
border-bottom: 1px solid #ccc;
color: #333;
display: block;
background: #efefef;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));
background: -ms-linear-gradient(bottom, #efefef, #fafafa);
background: -moz-linear-gradient(center bottom, #efefef 0%, #fafafa 100%);
background: -o-linear-gradient(bottom, #efefef, #fafafa);
filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";
box-shadow: inset 0px 1px 1px white;
} .left-menu .menu-body .static-menu a:hover {
color: #2F72AB;
border-left: 2px solid #2F72AB;
} .left-menu .menu-body .static-menu a.active {
color: #2F72AB;
border-left: 2px solid #2F72AB;
} .multi-menu .item {
background-color: white;
} .multi-menu .item > .title {
padding: 10px 5px;
border-bottom: 1px solid #dddddd;
cursor: pointer;
color: #333;
display: block;
background: #efefef;
background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #efefef), color-stop(1, #fafafa));
background: -ms-linear-gradient(bottom, #efefef, #fafafa);
background: -o-linear-gradient(bottom, #efefef, #fafafa);
filter: progid:dximagetransform.microsoft.gradient(startColorStr='#e3e3e3', EndColorStr='#ffffff');
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorStr='#fafafa',EndColorStr='#efefef')";
box-shadow: inset 0 1px 1px white;
} .multi-menu .item > .body {
border-bottom: 1px solid #dddddd;
} .multi-menu .item > .body a {
display: block;
padding: 5px 20px;
text-decoration: none;
border-left: 2px solid transparent;
font-size: 13px; } .multi-menu .item > .body a:hover {
border-left: 2px solid #2F72AB;
} .multi-menu .item > .body a.active {
border-left: 2px solid #2F72AB;
}
<div class="multi-menu"> {% for menu in menu_list %}
<div class="item">
<div class="title"> <i class="fa {{ menu.icon }}"></i> {{ menu.title }}</div>
<div class="body">
{% for child in menu.children %}
<a href="{{ child.url }}"> {{ child.title }} </a>
{% endfor %} </div> </div> {% endfor %} </div>
layout.html应用上
{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>路飞学城</title>
<link rel="shortcut icon" href="{% static 'imgs/luffy-study-logo.png' %} ">
<link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.css' %} "/>
<link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.css' %} "/>
<link rel="stylesheet" href="{% static 'css/commons.css' %} "/>
<link rel="stylesheet" href="{% static 'css/nav.css' %} "/>
<link rel="stylesheet" href="{% static 'rbac/css/menu.css' %} "/>
<style>
body {
margin: 0;
} .no-radius {
border-radius: 0;
} .no-margin {
margin: 0;
} .pg-body > .left-menu {
background-color: #EAEDF1;
position: absolute;
left: 1px;
top: 48px;
bottom: 0;
width: 220px;
border: 1px solid #EAEDF1;
overflow: auto;
} .pg-body > .right-body {
position: absolute;
left: 225px;
right: 0;
top: 48px;
bottom: 0;
overflow: scroll;
border: 1px solid #ddd;
border-top: 0;
font-size: 13px;
min-width: 755px;
} .navbar-right {
float: right !important;
margin-right: -15px;
} .luffy-container {
padding: 15px;
} </style> </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;">路飞学城 </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">管他什么菜单</a>
<a href="#" class="more-item">实在是编不了</a>
</div>
</div>
</div> <div class="right-menu right clearfix"> <div class="user-info right">
<a href="#" class="avatar">
<img class="img-circle" src="{% static 'imgs/default.png' %}">
</a> <div class="more-info">
<a href="#" class="more-item">个人信息</a>
<a href="#" class="more-item">注销</a>
</div>
</div> <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">
<div class="menu-body"> {# <a href="/customer/list/" class="active">#}
{# <span class="icon-wrap"><i class="fa fa-connectdevelop"></i></span> 客户管理</a>#}
{# <a href="/payment/list/">#}
{# <span class="icon-wrap"><i class="fa fa-code-fork"></i></span> 账单管理</a>#}
{% load rbac %}
{% menu request %} </div>
</div>
<div class="right-body">
<div>
<ol class="breadcrumb no-radius no-margin" style="border-bottom: 1px solid #ddd;"> <li><a href="#">首页</a></li>
<li class="active">客户管理</li> </ol>
</div>
{% block content %} {% endblock %}
</div>
</div> <script src="{% static 'js/jquery-3.3.1.min.js' %} "></script>
<script src="{% static 'plugins/bootstrap/js/bootstrap.js' %} "></script> <script>
$('.multi-menu .title').click(function () {
$(this).next().toggleClass('hide') }) </script> {% block js %} {% endblock %}
</body>
</html>
crm 动态一级二级菜单的更多相关文章
- 巨蟒django之权限7:动态生成一级&&二级菜单
内容回顾: . 权限的控制 . 表结构设计 存权限的信息 用户表 - name 用户名 - pwd 密码 - roles 多对多 角色表 - name - permissions 多对多 权限表 - ...
- 关于expanded一级二级菜单数据的分组排序
最新再弄关于expandedlistview相关的东西,所以需求是需要对一级菜单根据时间排序,同时二级菜单也需要根据时间排序,距离现在最近的时间显示在最前面. 效果就是如下: --group2 -- ...
- django中动态生成二级菜单
一.动态显示二级菜单 1.修改权限表结构 (1)分析需求,要求左侧菜单如下显示: 客户管理: 客户列表 账单管理: 账单列表 (2)修改rbac下的models.py,修改后代码如下: from dj ...
- python 全栈开发,Day108(客户管理之权限控制,客户管理之动态"一级"菜单,其他应用使用rbac组件,django static文件的引入方式)
一.客户管理之权限控制 昨天的作业,有很多不完善的地方 下载代码,基本实现权限验证 https://github.com/987334176/luffy_permission/archive/v1.2 ...
- python 全栈开发,Day109(客户管理之动态"二级"菜单)
昨日内容回顾 1. 权限有几张表? 2. 简述权限流程? 3. 为什么要把权限放入session? 4. 静态文件和模块文件 5. 相关技术点 - orm查询 - 去空 - 去重 - 中间件 - in ...
- css 实现动态二级菜单
动态实现简单的二级菜单 当鼠标放到一级标签上时,鼠标会变成小手的形状 展示二级菜单,源码如下,复制即可直接使用 <!DOCTYPE html> <html lang="en ...
- 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。
用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...
- html和css实现一级菜单和二级菜单学习笔记
实现一级菜单: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> ...
- CSS之实现二级菜单动态出现
一直觉得二级菜单的出现效果仅仅有js才干控制.今天研究了一下阿里巴巴站点的首页,才发现,原来二级菜单的动态显示也能够使用CSS来控制,原来对CSS是静态的东西一直是误解它了,CSS也能够实现动态的效果 ...
随机推荐
- Golang 学习权威网站
Golang 是一个开源的编程语言,它能让构造简单.可靠且高效的软件变得容易. Golang 是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发 ...
- SQLServer之创建AFETER DELETE触发器
DML AFTER DELETE触发器创建原理 触发器触发时,系统自动在内存中创建deleted表或inserted表,inserted表临时保存了插入或更新后的记录行,deleted表临时保存了删除 ...
- LeetCode算法题-Fibonacci Number(Java实现)
这是悦乐书的第250次更新,第263篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第117题(顺位题号是509).Fibonacci数字,通常表示为F(n),形成一个称为 ...
- Git的可视化工具SourceTree管理代码 SourceTree的使用
出处:https://blog.csdn.net/android_zhengyongbo/article/details/72885860 其他参考资料https://www.cnblogs.com/ ...
- NSSM安装服务
NSSM是一个服务封装程序,它可以将普通exe程序封装成服务,使之像windows服务一样运行.同类型的工具还有微软自己的srvany,不过nssm更加简单易用,并且功能强大.它的特点如下: 支持普通 ...
- Spring Security(二十九):9.4.1 ExceptionTranslationFilter
ExceptionTranslationFilter is a Spring Security filter that has responsibility for detecting any Spr ...
- nginx与fastdfs配置详解与坑
nginx与fastdfs配置详解与坑 环境 ubantu19.04 fastdfs-5.11 fastdfs-nginx-module-1.20 libfastcommon-1.0.39 nginx ...
- Linux内核入门到放弃-页缓存和块缓存-《深入Linux内核架构》笔记
内核为块设备提供了两种通用的缓存方案. 页缓存(page cache) 块缓存(buffer cache) 页缓存的结构 在页缓存中搜索一页所花费的时间必须最小化,以确保缓存失效的代价尽可能低廉,因为 ...
- 多数据库有序GUID
背景 常见的一种数据库设计是使用连续的整数为做主键,当新的数据插入到数据库时,由数据库自动生成.但这种设计不一定适合所有场景. 随着越来越多的使用Nhibernate.EntityFramework等 ...
- HNOI2019做题笔记
代码比较长所以直接去LOJ看吧- 鱼(计算几何.向量) 比较套路的内容:枚举\(D\),对于其他所有点按照\(D\)极角排序,按照极角序枚举\(A\),这样垂直于\(AD\)的线也会以极角序旋转,可以 ...