博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
权限组件(2):二级菜单
阅读量:6151 次
发布时间:2019-06-21

本文共 5210 字,大约阅读时间需要 17 分钟。

二级菜单效果图

 

一、把一级菜单从权限表里抽离出来,单独创建一个表

rbac/models

Menu

class Menu(models.Model):    """    菜单表    """    title = models.CharField(verbose_name='一级菜单的名称', max_length=32)    icon = models.CharField(verbose_name='图标', max_length=32, null=True, blank=True)    def __str__(self):        return self.title

 

Permission

class Permission(models.Model):    """    权限表    """    title = models.CharField(verbose_name='标题', max_length=32)    url = models.CharField(verbose_name='含正则的URL', max_length=128)    menu = models.ForeignKey(verbose_name='所属菜单', to=Menu, null=True, blank=True,                             help_text='null表示不是菜单,非null表示是二级菜单', on_delete=models.CASCADE                             )    def __str__(self):        return self.title

 

 

二、修改初始化权限

rbac/service/init_permission.py

思路:

  1. 获取一级菜单和二级菜单的信息
  2. 找出有menu_id的菜单(可以做二级菜单的)
  3. 将一级菜单的id作为key,values还是一个字典,里面储存一级菜单的标题、图标和二级菜单。

 代码:

from permission_learn import settingsdef init_permission(current_user, request):    """    用户权限的初始化    :param current_user:  当前登录用户    :param request:    :return:    """    permission_menu_queryset = current_user.roles.filter(permissions__isnull=False).values(        'permissions__id',        'permissions__title',        'permissions__url',        'permissions__menu_id',  # +        'permissions__menu__title',  # +        'permissions__menu__icon',  # +    ).distinct()    menu_dict = {}    permission_list = []    for item in permission_menu_queryset:        permission_list.append(item['permissions__url'])        menu_id = item['permissions__menu_id']        if not menu_id:            continue        second_menu = {
'title': item['permissions__title'], 'url': item['permissions__url']} if menu_id in menu_dict: menu_dict[menu_id]['second_menu'].append(second_menu) else: menu_dict[menu_id] = { 'title': item['permissions__menu__title'], 'icon': item['permissions__menu__icon'], 'second_menu': [second_menu, ] } request.session[settings.PERMISSION_SESSION_KEY] = permission_list request.session[settings.MENU_SESSION_KEY] = menu_dict"""客户列表 /customer/list/ 1 ForeignKey --> 1 客户管理 fa-hdd-o 添加客户 /customer/add/ null 编辑客户 /customer/edit/(?P
\d+)/ null 删除客户 /customer/del/(?P
\d+)/ null"""

 

 

三、渲染到模板

rbac/templatetags/rbac.py

import refrom collections import OrderedDictfrom django.conf import settingsfrom django.template import Libraryregister = Library()@register.inclusion_tag('rbac/multi_menu.html')def multi_menu(request):    menu_dict = request.session[settings.MENU_SESSION_KEY]    # 对字典的key进行排序。得到的结果是只包含Key的列表,类似这样的 [1,2,3]    key_list = sorted(menu_dict)    # 空的有序字典    ordered_dict = OrderedDict()  # 有序字典,按照我们想要的顺序展示    current_path = request.path    for key in key_list:        menu = menu_dict[key]  # {'title':'客户管理','icon':'fa fa-book','second_menu':[二级菜单1,二级菜单2,...]}        menu['class'] = 'hide'  # 隐藏二级菜单        for second_menu in menu['second_menu']:            regex = '^%s$' % second_menu['url']            if re.match(regex, current_path):                second_menu['class'] = 'active'                menu['class'] = ''  # 显示点中的二级菜单        ordered_dict[key] = menu    context = {        'menus': ordered_dict    }    return context

 

 

需要注意的是对字典的key进行排序得到的结果是只包含Key的列表,menu_dict的key是menu_id,最后得到这样的 [1,2,3...]的结果

通过templatestag渲染二级菜单到模板:rbac/templates/rbac/multi_menu.html

{% for menu in menus.values %}
{
{ menu.title }}
{% endfor %}

 

layout.html页面只需要把一级菜单的templates替换成二级菜单的就行

-       {% menu request %}    +       {% multi_menu request %}

 

js代码:rbac/static/rbac/js/rbac.js

$('.multi-menu .title').click(function () {    $(this).next().toggleClass('hide');});

toggleClass检查每个元素中指定的类。如果不存在则添加类,如果已设置则删除之。这就是所谓的切换效果。

 

css代码:rbac/static/rbac/css/rbac.css

'''.multi-menu .item {}.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;}'''

 

中间件不需要改动

 

转载于:https://www.cnblogs.com/lshedward/p/10494653.html

你可能感兴趣的文章
Windows 8.1 应用再出发 - 视图状态的更新
查看>>
自己制作交叉编译工具链
查看>>
Qt Style Sheet实践(四):行文本编辑框QLineEdit及自动补全
查看>>
[物理学与PDEs]第3章习题1 只有一个非零分量的磁场
查看>>
深入浅出NodeJS——数据通信,NET模块运行机制
查看>>
onInterceptTouchEvent和onTouchEvent调用时序
查看>>
android防止内存溢出浅析
查看>>
4.3.3版本之引擎bug
查看>>
SQL Server表分区详解
查看>>
使用FMDB最新v2.3版本教程
查看>>
STM32启动过程--启动文件--分析
查看>>
垂死挣扎还是涅槃重生 -- Delphi XE5 公布会归来感想
查看>>
淘宝的几个架构图
查看>>
linux后台运行程序
查看>>
Python异步IO --- 轻松管理10k+并发连接
查看>>
Oracle中drop user和drop user cascade的区别
查看>>
登记申请汇总
查看>>
Android Jni调用浅述
查看>>
CodeCombat森林关卡Python代码
查看>>
第一个应用程序HelloWorld
查看>>