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'
}] >

數據處理:

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組件封裝

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章