二级菜单 权限

在一级菜单基础上修改  

修改modles ,添加一张表

例:

from django.db import models


#一级菜单
class Menu(models.Model):
title=models.CharField(max_length=32,unique=True) #unique=True 唯一的
icon=models.CharField(max_length=32,verbose_name='图标',null=True,blank=True)

class Meta:
verbose_name_plural = '菜单表'
verbose_name = '菜单表'

def __str__(self):
return self.title

#权限表 有关联Menu的是二级菜单 没有关联Menu的不是二级菜单,是不可以做菜单的权限
class Permission(models.Model):
title=models.CharField(max_length=32,verbose_name='标题')
url=models.CharField(max_length=32,verbose_name='权限')
menu=models.ForeignKey(to='Menu',null=True,blank=True)

class Meta:
verbose_name_plural='权限表'
verbose_name='权限表'
def __str__(self):
return self.title

#部门表
class Role(models.Model):
name=models.CharField(max_length=32,verbose_name='部门名字')
permissions=models.ManyToManyField(to='Permission',verbose_name='部门所拥有的权限',blank=True)

class Meta:
verbose_name_plural='部门表'
verbose_name='部门表'
def __str__(self):
return self.name

#用户表
class User(models.Model):
name=models.CharField(max_length=32,verbose_name='用户名')
password=models.CharField(max_length=32,verbose_name='密码')
roles=models.ManyToManyField(to='Role',verbose_name='用户所在的部门',blank=True)

class Meta:
verbose_name_plural='用户表'
verbose_name='用户表'
def __str__(self):
return self.name
#记得更新2个命令
admin更改代码:
from django.contrib import admin

from rbac import models

#在页面显示关于权限表的内容
class PermissionAdmin(admin.ModelAdmin):
list_display = ['title','url'] #页面显示内容
list_editable = ['url',] #页面可编辑内容


admin.site.register(models.Permission,PermissionAdmin)
admin.site.register(models.Role)
admin.site.register(models.User)
admin.site.register(models.Menu)


中间件代码:
from django.utils.deprecation import MiddlewareMixin  #中间模块
from django.conf import settings #配置
import re
from django.shortcuts import render,redirect,HttpResponse

class PermissionMiddleware(MiddlewareMixin):
#对权限进行校验
def process_request(self,request):
#当前的输入的url
ret_url=request.path_info
#用re match判断白名单 在setting中的白名单 判断当前这个url 是否在 白名单中
for i in settings.WHITE_URL_LIST:
if re.match(i,ret_url):
return
#在session中获取当前用户的权限信息
permission_list=request.session.get(settings.PERMISSION_SESSION_KEY)

#对单个人的权限校验
for i in permission_list:
url=i['url'] #权限已字典形式存放 所有取key值
if re.match('^{}$'.format(url),ret_url): #ret_url 变成当前再次的访问的路径
return
else:
return HttpResponse('没有权限')

检验自行定义的函数代码:
from django.conf import settings

def init_permission(request,user):
# 1.查看当前用户的权限 values 出来的是字典
permissions_query = user.roles.filter(permissions__url__isnull=False).values(
'permissions__url',
'permissions__title',
'permissions__menu_id',
"permissions__menu__title",
"permissions__menu__icon",
).distinct()

# 存放权限信息
permissions_list = []
# 存放菜单信息
menu_dict = {}
for item in permissions_query:
permissions_list.append({'url': item['permissions__url']})
menu_id=item.get('permissions__menu_id')# 获取一级菜单的权限
if not menu_id: #没有id的跳出往下走
continue
# 如果id不在字典里 就添加
if menu_id not in menu_dict:
menu_dict[menu_id]={
'title': item['permissions__menu__title'],
'icon': item['permissions__menu__icon'],
'children': [
{'title': item['permissions__title'], 'url': item['permissions__url']}
]
}
else: #如果id在字典就添加 children的信息
menu_dict[menu_id]['children'].append(
{'title': item['permissions__title'], 'url': item['permissions__url']})

# 将权限信息 和菜单信息写入 session中
request.session[settings.PERMISSION_SESSION_KEY] = permissions_list
request.session[settings.MENU_SESSION_KEY] = menu_dict

添加的cs样式:
.static-menu .icon-wrap {
width: 20px;
display: inline-block;
text-align: center;
}

.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;
}

.static-menu a:hover {
color: #2F72AB;
border-left: 2px solid #2F72AB;
}

.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;
}

添加的js代码:
$('.item .title').click(function () {
$(this).next().toggleClass('hide')
});


自定义inclusion_tag html代码
<div class="multi-menu">
{% for item in menu_list.values %}
<div class="item">
<div class="title"><i class="fa {{ item.icon }}"></i> {{ item.title }}</div> {# 一级目录 #}
<div class="body hide">{# 二级目录 #}
{% for child in item.children %}
<a href="{{ child.url }}">{{ child.title }}</a>
{% endfor %}

</div>
</div>

{% endfor %}
</div>

自定义inclusion_tag 函数代码:

from django import template
from django.conf import settings
register=template.Library()

@register.inclusion_tag('rbac/menu.html')
def menu(request):
#获取菜单里的权限信息
menu_list=request.session.get(settings.MENU_SESSION_KEY)

return {'menu_list':menu_list}

在setting中的和一级菜单 配置一样 注意添加 app, 中间件, 白名单 ,权限配置


猜你喜欢

转载自www.cnblogs.com/xdlzs/p/9879808.html