Django之左侧菜单栏权限和二级菜单

一.左侧菜单栏权限

像下面的这种左侧菜单栏如果用户没有权限就直接不展示,不然没权限展示了也没什么用
在这里插入图片描述
实现思路:
在Permission表中加一个字段用来标记是否是左侧菜单,通过这个字段来判断用户是否有左侧菜单栏的权限。

class Permission(models.Model):
    url = models.CharField(max_length=48)
    title = models.CharField(max_length=32)
    is_menu = models.BooleanField(default=False)   # 标识左侧菜单栏
    icon = models.CharField(max_length=32, null=True, blank=True)

    def __str__(self):
        return self.title

将获取到的左侧菜单信息放到session中:

def permission(request,user_obj):
    # 登录认证
    request.session['is_login'] = True

    # 权限认证
    permissions_list = user_obj.roles.values(
        'Permissions__url',
        'Permissions__title',
        'Permissions__is_menu',
        'Permissions__icon',

    ).distinct()
	# 权限认证
    request.session[settings.PERMISSIONS_KEY] = list(permissions_list)


    # 左侧菜单栏认证权限
    menu_list = []
    for menu in permissions_list:
        if menu.get('Permissions__is_menu'):
            menu_list.append(menu)
    request.session[settings.MENU_KEY] = menu_list

使用模板标签生成左侧菜单栏:

from django import template
from django.conf import settings

register = template.Library()
@register.inclusion_tag('menu.html')
def menu(request):
    menu_list = request.session.get(settings.MENU_KEY)
    current_path = request.path
    for path in menu_list:
        if path == current_path:
            path['class'] = 'active'
    return {'menu_list':menu_list}

menu.html:

<div class="static-menu">
    {% for menu in menu_list %}
    <a href="{{ menu.Permissions__url }}" class="{{ menu.class }}">
        <span class="icon-wrap"><i class="{{ menu.Permissions__icon }}"></i></span>{{ menu.Permissions__title }}</a>
    {% endfor %}
</div>

结果:
用户只有一个菜单栏权限:
在这里插入图片描述
用户有所有菜单栏权限:
在这里插入图片描述

二.二级菜单

需求:想要实现下面左侧菜单中有二级菜单,点击之后有下拉选项

在这里插入图片描述
实现思路:
又要对表进行操作了,一级菜单对应多个二级菜单,可以创建一个一级菜单表专门用来放一级菜单,那么二级菜单就是我们之前创建好的Permission表,这个之前是用来放url的,在这个表中定义一个外键menus关联到一级菜单中。

创建表:

一级菜单表:

class Menu(models.Model):
    title = models.CharField(max_length=48)
    icon = models.CharField(max_length=32, null=True, blank=True)
    """
        id    title
        1     销售管理
        2     财务管理
    """
    def __str__(self):
        return self.title

二级菜单表:

class Permission(models.Model):
    url = models.CharField(max_length=48)
    title = models.CharField(max_length=32)
    menus = models.ForeignKey(to='Menu',null=True,blank=True)
    """
     id   url   title            menus
     1    x     客户展示          2
     2    xx    添加客户          None
     3          删除客户          None
     4          缴费展示          1 
     5          缴费编辑          None
     6          纳税管理          1
    """
    # 这里就不需要这两个字段了 因为这里标识的是一级菜单 现在有了一级菜单的表了
    # is_menu = models.BooleanField(default=False)   # 标识左侧菜单栏
    # icon = models.CharField(max_length=32, null=True, blank=True)

    def __str__(self):
        return self.title

最终的结果:
在这里插入图片描述
获取数据:
客户展示有销售管理一个二级菜单,缴费展示有纳税管理和缴费展示两个二级菜单

< QuerySet[{
	'Permissions__id': 2,
	'Permissions__url': '/app05/customer/list/',
	'Permissions__title': '客户展示',
	'Permissions__menus__id': 1,
	'Permissions__menus__title': '销售管理',
	'Permissions__menus__icon': 'fa fa-bath fa-spin'
}, {
	'Permissions__id': 6,
	'Permissions__url': '/app05/payment/list/',
	'Permissions__title': '缴费展示',
	'Permissions__menus__id': 2,
	'Permissions__menus__title': '财务管理',
	'Permissions__menus__icon': 'fa fa-rmb fa-spin'
}, {
	'Permissions__id': 10,
	'Permissions__url': '/app05/nashui/',
	'Permissions__title': '纳税管理',
	'Permissions__menus__id': 2,
	'Permissions__menus__title': '财务管理',
	'Permissions__menus__icon': 'fa fa-rmb fa-spin'
}] >

数据处理:

扫描二维码关注公众号,回复: 11599700 查看本文章
menu_dict = {}
for menu in permissions_list:
    if menu.get('Permissions__menus__id'):
        if menu.get('Permissions__menus__id') in menu_dict:
            menu_dict[menu.get('Permissions__menus__id')]['children'].append(
                {'url': menu_dict[menu.get('Permissions__url')], 'title': menu_dict[menu.get('Permissions__title')]}
            )
        else:
            menu_dict[menu.get('Permissions__menus__id')] = {
                'title':menu_dict[menu.get('Permissions__menus__title')],   # 一级菜单
                'icon':menu_dict[menu.get('Permissions__menus__icon')],     # 一级菜单icon 图标
                'children':[
                    {'url':menu_dict[menu.get('Permissions__url')],'title':menu_dict[menu.get('Permissions__title')]}  # 二级菜单
                ]
            }
          
格式为:
{
1{
'title':'销售管理'  # 一级菜单
'icon':'fa fa-bath fa-spin'
'children':[
	'url':'/customer/list/'
	'title':'客户展示'
]
}
}

结果:
在这里插入图片描述
前端效果:
自定义标签中:

@register.inclusion_tag('menu.html')
def menu(request):
    menu_dict= request.session.get(settings.MENU_KEY)
    return {'menu_dict':menu_dict}

menu.html:

<div class="multi-menu">
    {% for menu_k,menu_v in menu_dict.items %}
        <div class="item">
        <div class="title"> {{ menu_v.title }}</div>
            <div class="body hidden">
                {% for ermenu in menu_v.children %}
                    <a href="{{ ermenu.url }}">{{ ermenu.title }}</a>
                {% endfor %}
            </div>
        </div>
    {% endfor %}
</div>

母版中js效果:

{% block js %}
    <script>
    $('.multi-menu .title').click(function () {
        $(this).siblings('.body').toggleClass('hidden').parent().siblings().find('.body').addClass('hidden')
    })
    </script>
 {% endblock %}

三.RBAC组件封装

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_39253370/article/details/106355179
今日推荐