• rbac组件之动态一级菜单栏实现


    上一个版本,前端页面的左侧菜单栏在HTML中写死了,左侧菜单栏需要根据业务的不同而展示不同的菜单栏!!!

     那么在当前的例子中,哪些可以成为菜单栏呢?

    """
    客户管理
        客户列表:/customer/list/
        添加客户:/customer/add/
        删除客户:/customer/list/(?P<cid>\d+)/
        修改客户:/customer/edit/(?P<cid>\d+)/
        批量导入:/customer/import/
        下载模板:/customer/tpl/
    账单管理
        账单列表:/payment/list/
        添加账单:/payment/add/
        删除账单:/payment/del/(?P<pid>\d+)/
        修改账单:/payment/edit/<?P<pid>\d+/
    """
    
    """
    客户列表和账单列表两个可以成为菜单
    """

    根据上一个版本的表结构也可以在所有URL中找出可以做菜单的URL,但是会很麻烦,那么此时可以在Permission权限表中,加入一个字段来标识来此URL是否可以做菜单

    class Permission(models.Model):
        """权限表"""
        title = models.CharField(
            verbose_name="权限名称",
            max_length=32,
        )
        url = models.CharField(
            verbose_name="含正则URL",
            max_length=128,
        )
        is_menu = models.BooleanField(
            verbose_name="是否可以做菜单",
            default=False,
        )
        icon = models.CharField(
            verbose_name="图标",
            max_length=64,
    blank=True,
    ) def __str__(self): return self.title

    菜单栏的图标,使用的是fontawesome,图标的形态不同,仅仅是class属性fa后面的代码不同,如:<i class="fa fa-address-book" aria-hidden="true"></i>

    权限初始化的时候,在session中再加入一条数据信息,即当前用户的菜单栏信息即可

    from django.conf import settings
    
    
    def init_permission(current_user, request):
        permission_queryset = current_user.roles.filter(
            permissions__isnull=False,
        ).values(
            "permissions__id",
            "permissions__url",
            "permissions__title",
            "permissions__is_menu",
            "permissions__icon",
        ).distinct()
        permission_list = []
        menu_list = []
        for item in permission_queryset:
            permission_list.append(item["permissions__url"])
            if item["permissions__is_menu"]:
                temp = {
                    "url": item["permissions__url"],
                    "title": item["permissions__title"],
                    "icon": item["permissions__icon"],
                }
                menu_list.append(temp)
        request.session[settings.PERMISSION_SESSION_KEY] = permission_list
        request.session[settings.MENU_LIST] = menu_list
    
    
    """
    permission_list = [
        '/customer/list/', 
        '/customer/add/', 
        '/customer/list/(?P<cid>\\d+)/', 
        '/customer/edit/(?P<cid>\\d+)/', 
        '/customer/import/', 
        '/customer/tpl/', 
        '/payment/list/', 
        '/payment/add/', 
        '/payment/del/(?P<pid>\\d+)/', 
        '/payment/edit/<?P<pid>\\d+/'
    ]
    menu_list = [
        {'url': '/customer/list/', 'title': '客户列表', 'icon': 'fa-address-book'}, 
        {'url': '/payment/list/', 'title': '账单列表', 'icon': 'fa-money'}
    ]
    """

    此时,在session中存在两条数据信息,一条是权限,一条是菜单,权限已经完成了,当前问题是如何把菜单数据给渲染到前端页面呢?如果是在每一个需要用到菜单栏的HTML去编写代码,那么会很繁琐,虽然相同页面可以继承一个母版,但是不符合rbac组件的

    编写原则,即拿即用。

    那么可以将左侧菜单栏写成一个inclusion_tag,前端哪里需要直接调用即可,无需编写其余代码

    rbac/templatetags/rbac.py

    from django.template import Library
    from django.conf import settings
    import re
    
    register = Library()
    
    
    @register.inclusion_tag("rbac/menu.html")
    def menu(request):
        menu_list = request.session.get(settings.MENU_LIST)
        for item in menu_list:
            url = "^%s$" % item["url"]
            if re.match(url, request.path_info):
                item["class"] = "active"
        return {"menu_list": menu_list}

    rbac/templates/rbac/menu.html

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

    前端调用

    {# 指的是templatetags/rbac.py #}
    {% load rbac %}
    
    {# 需要用到一个参数request,所以调用时需要给其传参(inclusion_tag最多只能有两个参数) #}
    {% menu request %}

     rbac组件结构

     总结:

    """
    1 在Permission权限表加上is_menu字段,即可方便实现菜单栏的效果
    2 在Permission权限表加上icon字段,方便菜单栏图标的渲染
    3 在权限初始化中,根据is_menu的值(字段类型为布尔值)来判断是否可以做菜单,然后把可以做菜单的URL提取到另一个列表存储,该列表中数据是一个个字典,每个字典都有该菜单的URL、title、icon数据信息
    4 为了前端的简单调用,rbac组件写了一个inclusion_tag,前端哪里需要直接调用该inclusion_tag即可
    """

     rbac动态一级菜单源码链接

    链接:https://pan.baidu.com/s/11CNodIt3XE_LCPeTjB5pRw
    提取码:abab

  • 相关阅读:
    c#缓存技术(Dictionary)
    反射Reflection创建
    SQL Server手注之延时型盲注
    MySQL——事务
    MySQL——NULL值处理
    MySQL——连接的使用
    SQL server手注之报错注入
    SQL Serves手注之联合查询注入
    MySQL手注之ROOT权限处理
    MySQL——正则表达式
  • 原文地址:https://www.cnblogs.com/xuewei95/p/15841031.html
Copyright © 2020-2023  润新知