zoukankan      html  css  js  c++  java
  • 一级动态菜单的功能

    动态菜单 一级菜单的实现:

    1.先解释一下权限:

           首先我们要知道,我们是根据权限,来决定当前这个用户可以做什么样的操作。那么问题来了, 我要如何在 页面上展示, 不同的用户访问时, 他有哪些可以操作的按钮。

    比如: CEO来的时候,他可以做任何事情。那么我就需要把所有的 按钮给他展示出来。
      可以添加,可以查看,可以编辑,可以修改。 那么最少就需要4个按钮。

      销售专员,登录的时候。 他只有 查看,和添加的功能。 那么我就只需要给他展示两个按钮。

    2.然后再说一说菜单:

      菜单是一个可以点击之后,我能够看到,这个菜单下 拥有哪些功能。  或者哪些 二级菜单。
    菜单是一个 有标题 有 url 的这个一个按钮。 那么我们的权限表 也是这样的结构。 但是还有一个问题,我们的权限表中有哪些记录(也就是哪些url 可以当作菜单使用)。
      客户列表 毋庸置疑,这个可以用来当作一个菜单。 添加客户也可以当作一个菜单(当然也可以将他当作 客户列表菜单下的一个功能)。  编辑和删除,就不能作为一个菜单。  因为编辑和删除都是 要对一个指定的客户进行操作了。  如果作为菜单使用,我们就需要在菜单下面,把所有的客户全部都列出来。 这么做太傻了。

    我们要的应该是这样一个效果 说再多也不如一张图实在 上图:

    这是一张整体的效果图, 信息管理是一级菜单。他没有URL。只是用来区分不同功能的二级菜单。客户列表和账单列表就是二级菜单了。二级菜单就有URL了,我这里都是查看页面的URL作为二级菜单:

     3. OK 效果大概是这样, 那么我们要怎么去实现:

      3.1  修改我们的权限表, 添加两个字段。  这个字段用来表示  我这条记录(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)
        # 默认为False 因为菜单少, 功能多。
        icon = models.CharField(verbose_name="图标", max_length=32, null=True, blank=True)
    
        def __str__(self):
            return self.title

    不要好奇,为什么图标是CharField。 因为我想使用 http://fontawesome.dashgame.com/ 这个网站的图标库。  只需要为标签添加一个 类。 就能拥有丰富的图标。 简单实用为啥不用。
    而且 只是需要下载一下,他的css框架, 并放到我们的static中, 最后再模板里面引入一下就ok。

    <link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.css' %} "/>

      3.2  登录的步骤,添加一个session记录。  这个记录保存  当前这个用户拥有的权限当中,可以被当作菜单来使用的 这条url

    因为我是开发rbac组件,所以添加session。 当然还是要着这个组件里完成喽。毕竟 web业务的 login视图,只是调用一下:上代码

     1 from django.conf import settings
     2 
     3 
     4 def init_permission(current_user, request):
     5     '''
     6     :param current_user: 当前请求 用户对象
     7     :param request:  当前请求 数据
     8     :return:
     9     '''
    10     # 2. 权限 初始化
    11     # 根据当前用户信息,获取当前用户所拥有的所有的权限(queryset对象 是不能直接放入,session中的)
    12     permission_queryset = current_user.roles.filter(permissions__isnull=False) 
    13         .values("permissions__url", "permissions__is_menu", "permissions__title", "permissions__icon") 
    14         .distinct()
    15 
    16     # 获取权限 和 菜单信息。  权限放在权限列表,菜单放在菜单列表
    17     menu_list = []
    18     permission_list = []
    19     for item in permission_queryset:
    20         permission_list.append(item.get("permissions__url"))
    21         if item.get("permissions__is_menu"):
    22             temp = {
    23                 "title": item.get("permissions__title"),  # 标题
    24                 "icon": item.get("permissions__icon"),  # 图标
    25                 "permissions__url": item.get("permissions__url"),  # 对应的跳转url
    26             }
    27             menu_list.append(temp)
    28     request.session[settings.PERMISSIONS_SESSION_KEY] = permission_list
    29     request.session[settings.MENU_SESSION_KEY] = menu_list
    rbacserviceinit_permission.py

    这里因为 又多了一个要添加到session中的数据。 但是循环遍历的还是原来的数据。所以做一点小优化。一次遍历,取出所有的url  和 可用作菜单的url。
    我这里用字典是因为,要进行模板渲染的时候,比较方便。


      3.3  然后就是,从session中取出,权限列表,进行验证。菜单列表,进行渲染菜单的工作了。

     这里使用一个  inclusion_tag() 的,自定义模板语法的装饰器。 他的作用是 将被装饰函数的 返回值。传进模板中进行渲染,然后返回给调用者渲染完成的html字符串。
    自定义模板语法的代码:

    from django.template import Library
    from django.conf import settings
    
    register = Library()
    
    
    @register.inclusion_tag("rbac/static_menu.html")
    def static_menu(request):
        '''
        创建一级菜单
        :return:
        '''
        path_info = request.path_info
        menu_list = request.session.get(settings.MENU_SESSION_KEY)
        return {"menu_list": menu_list, "path_info": path_info}
    rbac emplatetags bac_tags.py
    <div class="static-menu">
        {% for menu in menu_list %}
            {% if path_info == menu.permissions__url %}
                <a href="{{ menu.permissions__url }}" class="active">
                    <span class="icon-wrap"><i class="fa {{ menu.icon }}"></i></span>{{ menu.title }}</a>
            {% else %}
                <a href="{{ menu.permissions__url }}">
                    <span class="icon-wrap"><i class="fa {{ menu.icon }}"></i></span>{{ menu.title }}</a>
            {% endif %}
        {% endfor %}
    </div>
    rbac emplates bacstatic_menu.html

    OK  模板语法已经搞定了。  如何使用呢:
    直接到我的业务app中,调用这个 模板就可以。传入相应的参数。

    {% load rbac_tags %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.css' %} "/>
        <title>Title</title>
    </head>
    <body>
        <div class="left-menu">
            <div class="menu-body">
                {% static_menu request%}
            </div>
        </div>
    </body>
    </html>
    <--我这里只是为了 简洁,所以只是展示一下,使用的方法-->
    <-- 在我调用{% static_menu request%} 的地方。 传入request参数。最终返回的就是已经 渲染好了的 html字符串-->
    web emplateslayout.html
  • 相关阅读:
    子信息传递多个参数
    Oracle q' 简化单引号转义
    HTML的target属性中_blank、_self、_parent、_top含义
    数据库设计之“有时不得不违背的第三范式”
    Jquery下的Ajax调试方法
    JQuery.Ajax之错误调试帮助信息
    定时删除数据-用JOB
    数据分析
    机器学习数学基础
    机器学习数学基础
  • 原文地址:https://www.cnblogs.com/chengege/p/10697383.html
Copyright © 2011-2022 走看看