zoukankan      html  css  js  c++  java
  • 角色权限管理组件

    角色权限管理:role basic access control,简称rbac

    权限管理:
    表:
    	用户表
    	角色表
    	用户角色关系表
    	
    	菜单表
    	权限表
    	操作表
    	角色权限操作关系表
    	
    功能:
    	- 权限控制
    	- 动态菜单
    
    原理:
    - 权限控制
    	a. 登录时,获取当前用户所有权限,放置在Session中
    		request.session['rbac_permission_session_key'] = 'asdf'
    		{
    			'/index.html': [G,P...]
    		}
    	b. 其他请求,在session中检测是否具有权限
    		中间件 + 配置文件
    - 动态菜单
    	a. 登录时,获取当前用户菜单和权限,放置在Session中
    	
    	b. 其他请求,在session中获取菜单,动态生成(simple_tag)

    数据库表设计

    from django.db import models
    
    
    class User(models.Model):
        """
        用户表
        """
        username = models.CharField(verbose_name='用户名', max_length=32)
        password = models.CharField(verbose_name='密码', max_length=64)
        email = models.EmailField(verbose_name='邮箱')
    
        def __str__(self):
            return self.username
    
    
    class Role(models.Model):
        """
        角色表
        """
        caption = models.CharField(verbose_name='角色', max_length=32)
    
        def __str__(self):
            return self.caption
    
    
    class User2Role(models.Model):
        """
        用户角色关系表
        """
        user = models.ForeignKey(User, verbose_name='用户', related_name='roles')
        role = models.ForeignKey(Role, verbose_name='角色', related_name='users')
    
        def __str__(self):
            return '%s-%s' % (self.user.username, self.role.caption,)
    
    
    class Menu(models.Model):
        """
        菜单表
        """
        caption = models.CharField(verbose_name='菜单名称', max_length=32)
        parent = models.ForeignKey('self', verbose_name='父菜单', related_name='p', null=True, blank=True)
    
        def __str__(self):
            prev = ""
            parent = self.parent
            while True:
                if parent:
                    prev = prev + '-' + str(parent.caption)
                    parent = parent.parent
                else:
                    break
            return '%s-%s' % (prev, self.caption,)
    
    
    class Permission(models.Model):
        """
        权限
        """
        caption = models.CharField(verbose_name='权限', max_length=32)
        url = models.CharField(verbose_name='URL正则', max_length=128)
        menu = models.ForeignKey(Menu, verbose_name='所属菜单', related_name='permissions',null=True,blank=True)
    
        def __str__(self):
            return "%s-%s" % (self.caption, self.url,)
    
    
    class Action(models.Model):
        """
        操作:增删改查
        """
        caption = models.CharField(verbose_name='操作标题', max_length=32)
        code = models.CharField(verbose_name='方法', max_length=32)
    
        def __str__(self):
            return self.caption
    
    
    class Permission2Action2Role(models.Model):
        """
        权限操作关系表
        """
        permission = models.ForeignKey(Permission, verbose_name='权限URL', related_name='actions')
        action = models.ForeignKey(Action, verbose_name='操作', related_name='permissions')
        role = models.ForeignKey(Role, verbose_name='角色', related_name='p2as')
    
        class Meta:
            unique_together = (
                ('permission', 'action', 'role'),
            )
    
        def __str__(self):
            return "%s-%s-%s" % (self.permission, self.action, self.role,)
    ORM代码

    获取用户权限以及中间件权限控制

    URL路由系统
    #urls.py
    from app02 import views as views2
    
        url(r'^auto-login.html$', views2.login),
        url(r'^auto-index.html$', views2.index),
    
    中间件
    #settings.py
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'middleware.md.M1',
    ]
    
    配置中间件
    #md.py
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    import re
    class M1(MiddlewareMixin):
    
        def process_request(self,request,*args,**kwargs):
            valid = ['/auth-login.html','/auth-index.html']
            if request.path_info not in valid:
                action = request.GET.get('md') # GET
                user_permission_dict = request.session.get('user_permission_dict')
                if not user_permission_dict:
                    return HttpResponse('无权限')
    
                # action_list = user_permission_dict.get(request.path_info)
                flag = False
                for k,v in user_permission_dict.items():
                    if re.match(k,request.path_info):
                        if action in v:
                            flag = True
                            break
                if not flag:
                    return HttpResponse('无权限')
    
    
    视图函数
    #views.py
    def login(request):
        if request.method == "GET":
            return render(request,'login2.html')
        else:
            user_permission_dict = {
                '/ah-index.html/':["GET","POST","DEL","Edit"],
                '/order.html/':["GET","POST","DEL","Edit"],
                '/index-(d+).html/':["GET","POST","DEL","Edit"],
            }
            request.session['user_permission_dict'] = user_permission_dict
            return HttpResponse('登录成功')
    
    def index(request):
        # http://127.0.0.1:8000/auth-index.html?md=GET
        return HttpResponse('登陆,并且有权限才能看见我')
    权限控制示例

    输出动态菜单

    urlpatterns = [
        url(r'^app02_test.html', views2.app02_test),
    ]
    urls.py
    from django.contrib import admin
    
    # Register your models here.
    from app02 import models
    
    admin.site.register(models.User)
    admin.site.register(models.Role)
    admin.site.register(models.User2Role)
    admin.site.register(models.Menu)
    admin.site.register(models.Permission)
    admin.site.register(models.Action)
    admin.site.register(models.Permission2Action2Role)
    app02/admin.py
    def app02_test(request):
        """
        需要用户名或用户ID,产出:用户关联所有菜单
        :param request:
        :return:
        """
    
        # 所有菜单:处理成当前用关联的菜单
        all_menu_list = models.Menu.objects.all().values('id', 'caption', 'parent_id')
        """
        [
            {'id':1, 'caption':'菜单1', parent_id:None},
            {'id':2, 'caption':'菜单2', parent_id:None},
            {'id':3, 'caption':'菜单3', parent_id:None},
            {'id':4, 'caption':'菜单1-1', parent_id:1},
        ]
    
        {
            1:{'id':1, 'caption':'菜单1', parent_id:None,status:False,opened:False,child:[]},
            2:{'id':2, 'caption':'菜单2', parent_id:None,status:False,opened:False,child:[]},
            3:{'id':3, 'caption':'菜单3', parent_id:None,status:False,opened:False,child:[]},
            5:{'id':4, 'caption':'菜单1-1', parent_id:1,status:False,opened:False,child:[]},
        }
       """
        user = models.User.objects.filter(username='alex').first()
        role_list = models.Role.objects.filter(users__user=user)
        permission_list = models.Permission2Action2Role.objects.filter(role__in=role_list).values('permission__id',
                                                                                                  'permission__url',
                                                                                                  'permission__menu_id',
                                                                                                  'permission__caption').distinct()
    
    
    
        """
    
        [
            {'permission__url':'/order.html','permission__caption': '订单管理','permission__menu_id': 1 },
            {'permission__url':'/order.html','permission__caption': '订单管理','permission__menu_id': 2 },
            {'permission__url':'/order.html','permission__caption': '订单管理','permission__menu_id': 3 },
            {'permission__url':'/order.html','permission__caption': '订单管理','permission__menu_id': 4 },
        ]
        """
        ##### 将权限挂靠到菜单上 ########
        all_menu_dict = {}
        for row in all_menu_list:
            row['child'] = []  # 添加孩子
            row['status'] = False  # 是否显示菜单
            row['opened'] = False  # 是否默认打开
            all_menu_dict[row['id']] = row
    
    
    
    
        for per in permission_list:
            if not per['permission__menu_id']:
                continue
    
            item = {
                'id': per['permission__id'],
                'caption': per['permission__caption'],
                'parent_id': per['permission__menu_id'],
                'url': per['permission__url'],
                'status': True,
                'opened': False
            }
    
            # print(item["url"])
            if re.match(per['permission__url'],request.path_info):
            # if re.match(per['permission__url'], "/orders.html"):
                item['opened'] = True
            pid = item['parent_id']
            all_menu_dict[pid]['child'].append(item)
    
            # 将当前权限前辈status=True
            temp = pid  # 1.父亲ID
            while not all_menu_dict[temp]['status']:
                all_menu_dict[temp]['status'] = True
                temp = all_menu_dict[temp]['parent_id']
                if not temp:
                    break
    
            # 将当前权限前辈opened=True
            if item['opened']:
                temp1 = pid  # 1.父亲ID
                while not all_menu_dict[temp1]['opened']:
                    all_menu_dict[temp1]['opened'] = True
                    temp1 = all_menu_dict[temp1]['parent_id']
                    if not temp1:
                        break
        # ############ 处理菜单和菜单之间的等级关系 ############
        """
        all_menu_dict = {
            1:{'id':1, 'caption':'菜单1', parent_id:None,status:False,opened:False,child:[{'permission__url':'/order.html','permission__caption': '订单管理','permission__menu_id': 1 },]},
            2:{'id':2, 'caption':'菜单2', parent_id:None,status:False,opened:False,child:[]},
            3:{'id':3, 'caption':'菜单3', parent_id:None,status:False,opened:False,child:[]},
            5:{'id':4, 'caption':'菜单1-1', parent_id:1,status:False,opened:False,child:[]},
        }
    
    
        all_menu_list= [
            {'id':1, 'caption':'菜单1', parent_id:None,status:False,opened:False,child:[{'permission__url':'/order.html','permission__caption': '订单管理','permission__menu_id': 1 }, {'id':4, 'caption':'菜单1-1', parent_id:1,status:False,opened:False,child:[]},]},
            {'id':2, 'caption':'菜单2', parent_id:None,status:False,opened:False,child:[]},
            {'id':3, 'caption':'菜单3', parent_id:None,status:False,opened:False,child:[]},
    
        ]
        """
    
        result = []
        for row in all_menu_list:
            pid = row['parent_id']
            if pid:
                all_menu_dict[pid]['child'].append(row)
            else:
                result.append(row)
    
    
        ##################### 结构化处理结果 #####################
        # print(result)
        # for row in result:
        #     # print(row['caption'], row['status'], row['opened'], )
        #     print(row)
    
        ##################### 通过结构化处理结果,生成菜单开始 #####################
    
        def menu_tree(menu_list):
            tpl1 = """
            <div class='menu-item'>
                <div class='menu-header'>{0}</div>
                <div class='menu-body {2}'>{1}</div>
            </div>
            """
            tpl2 = """
            <a href='{0}' class='{1}'>{2}</a>
            """
    
            menu_str = ""
            for menu in menu_list:
                if not menu['status']:
                    continue
                # menu: 菜单,权限(url)
                if menu.get('url'):
                    # 权限
                    menu_str += tpl2.format(menu['url'],'active' if menu['opened'] else "",menu['caption'])
                else:
                    # 菜单
                    if menu['child']:
                        child_html = menu_tree(menu['child'])
                    else:
                        child_html = ""
                    menu_str += tpl1.format(menu['caption'], child_html,"" if menu['opened'] else 'hide')
    
            return menu_str
    
        menu_html = menu_tree(result)
    
    
    
    
        return render(request, "menu_html.html", {"menu_html":menu_html})
    app02/views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <style>
            .menu-body{
                margin-left: 20px;
            }
            .menu-body a{
                display: block;
            }
            .menu-body a.active{
                color: red;
            }
            .hide{
                display: none;
            }
        </style>
    </head>
    <body>
    
        {{ menu_html|safe }}
    
        <script src="/static/jquery-3.2.1.js"></script>
        <script>
            $(function () {
                $(".menu-header").click(function () {
                    $(this).next().removeClass("hide").parent().siblings().find(".menu-body").addClass("hide")
                })
            })
        </script>
    </body>
    </html>
    menu_html.html

    生成APP组件

    生成公共app
           - 权限限制
           - 生成菜单
    
    python3 manage.py startapp rbac
    
    #白名单url, 不验证
    
    VALID_URL = [
        '/app01/.*',
        '/app02/.*',
        '/login.html',
        '/logout.html',
    ]
    config.py
    from django.db import models
    
    
    class User(models.Model):
        """
        用户表
        """
        username = models.CharField(verbose_name='用户名', max_length=32)
        password = models.CharField(verbose_name='密码', max_length=64)
        email = models.EmailField(verbose_name='邮箱')
    
        def __str__(self):
            return self.username
    
    
    class Role(models.Model):
        """
        角色表
        """
        caption = models.CharField(verbose_name='角色', max_length=32)
    
        def __str__(self):
            return self.caption
    
    
    class User2Role(models.Model):
        """
        用户角色关系表
        """
        user = models.ForeignKey(User, verbose_name='用户', related_name='roles')
        role = models.ForeignKey(Role, verbose_name='角色', related_name='users')
    
        def __str__(self):
            return '%s-%s' % (self.user.username, self.role.caption,)
    
    
    class Menu(models.Model):
        """
        菜单表
        """
        caption = models.CharField(verbose_name='菜单名称', max_length=32)
        parent = models.ForeignKey('self', verbose_name='父菜单', related_name='p', null=True, blank=True)
    
        def __str__(self):
            prev = ""
            parent = self.parent
            while True:
                if parent:
                    prev = prev + '-' + str(parent.caption)
                    parent = parent.parent
                else:
                    break
            return '%s-%s' % (prev, self.caption,)
    
    
    class Permission(models.Model):
        """
        权限
        """
        caption = models.CharField(verbose_name='权限', max_length=32)
        url = models.CharField(verbose_name='URL正则', max_length=128)
        menu = models.ForeignKey(Menu, verbose_name='所属菜单', related_name='permissions',null=True,blank=True)
    
        def __str__(self):
            return "%s-%s" % (self.caption, self.url,)
    
    
    class Action(models.Model):
        """
        操作:增删改查
        """
        caption = models.CharField(verbose_name='操作标题', max_length=32)
        code = models.CharField(verbose_name='方法', max_length=32)
    
        def __str__(self):
            return self.caption
    
    
    class Permission2Action2Role(models.Model):
        """
        权限操作关系表
        """
        permission = models.ForeignKey(Permission, verbose_name='权限URL', related_name='actions')
        action = models.ForeignKey(Action, verbose_name='操作', related_name='permissions')
        role = models.ForeignKey(Role, verbose_name='角色', related_name='p2as')
    
        class Meta:
            unique_together = (
                ('permission', 'action', 'role'),
            )
    
        def __str__(self):
            return "%s-%s-%s" % (self.permission, self.action, self.role,)
    models.py
    #验证中间件
    
    
    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse
    from rbac import config
    import re
    
    
    class RbacMiddleware(MiddlewareMixin):
    
        def process_request(self,request,*args,**kwargs):
            for pattern in config.VALID_URL:
                if re.match(pattern,request.path_info):
                    return None
    
            action = request.GET.get('md') # GET
            user_permission_dict = request.session.get('user_permission_dict')
            if not user_permission_dict:
                return HttpResponse('无权限')
    
            # action_list = user_permission_dict.get(request.path_info)
            flag = False
            for k,v in user_permission_dict.items():
                if re.match(k,request.path_info):
                    if action in v:
                        flag = True
                        break
            if not flag:
                return HttpResponse('无权限')
    /middleware/md.py
    import re
    from rbac import models
    from django.utils.safestring import mark_safe
    
    def permission_session(user_id,request):
        """
    
        :param user_id:  rbac中的user表中一条数据id
        :param request:
        :return:
        """
        # obj = models.User.objects.filter(username='杨明').first()
        #
        # # x = models.User2Role.objects.filter(user_id=obj.id)
        # # [User2Role,User2Role,User2Role]
        #
        # role_list = models.Role.objects.filter(users__user_id=obj.id)
        # # [Role,]
        # from django.db.models import Count
        # # permission_list = models.Permission2Action2Role.objects.filter(role__in=role_list).values('permission__url','action__code').annotate(c=Count('id'))
        # permission_list = models.Permission2Action2Role.objects.filter(role__in=role_list).values('permission__url','action__code').distinct()
        """
        [
            {permission_url: '/index.html', action_code:'GET'},
            {permission_url: '/index.html', action_code:'POST'},
            {permission_url: '/index.html', action_code:'DEL'},
            {permission_url: '/index.html', action_code:'Edit'},
            {permission_url: '/order.html', action_code:'GET'},
            {permission_url: '/order.html', action_code:'POST'},
            {permission_url: '/order.html', action_code:'DEL'},
            {permission_url: '/order.html', action_code:'Edit'},
        ]
        放在Session中
        /index.html?md=GET
    
        {
            '/index.html': [GET,POST,DEL,Edit],
            '/order.html': [GET,POST,DEL,Edit],
        }
    
        """
    
        user_permission_dict = {
            '/ah-index.html': ["GET","POST","DEL","Edit"],
            '/order.html':  ["GET","POST","DEL","Edit"],
            '/index-(d+).html':  ["GET","POST","DEL","Edit"],
        }
    
        request.session['user_permission_dict'] = user_permission_dict
    
    
    def menu(user_id,current_url):
        """
        根据用户ID,当前URL:获取用户所有菜单以及权限,是否显示,是否打开
        :param user_id:
        :param current_url:
        :return:
        """
        # 所有菜单:处理成当前用关联的菜单
        all_menu_list = models.Menu.objects.all().values('id','caption','parent_id')
        user = models.User.objects.filter(id=user_id).first()
        role_list = models.Role.objects.filter(users__user=user)
        permission_list = models.Permission2Action2Role.objects.filter(role__in=role_list).values('permission__id','permission__url','permission__menu_id','permission__caption').distinct()
        ##### 将权限挂靠到菜单上 ########
        all_menu_dict = {}
        for row in all_menu_list:
            row['child'] = []      # 添加孩子
            row['status'] = False # 是否显示菜单
            row['opened'] = False # 是否默认打开
            all_menu_dict[row['id']] = row
    
        for per in permission_list:
            if not per['permission__menu_id']:
                continue
    
            item = {
                'id':per['permission__id'],
                'caption':per['permission__caption'],
                'parent_id':per['permission__menu_id'],
                'url': per['permission__url'],
                'status': True,
                'opened': False
            }
            if re.match(per['permission__url'],current_url):
                item['opened'] = True
            pid = item['parent_id']
            all_menu_dict[pid]['child'].append(item)
    
            # 将当前权限前辈status=True
            temp = pid # 1.父亲ID
            while not all_menu_dict[temp]['status']:
                all_menu_dict[temp]['status'] = True
                temp = all_menu_dict[temp]['parent_id']
                if not temp:
                    break
    
            # 将当前权限前辈opened=True
            if item['opened']:
                temp1 = pid # 1.父亲ID
                while not all_menu_dict[temp1]['opened']:
                    all_menu_dict[temp1]['opened'] = True
                    temp1 = all_menu_dict[temp1]['parent_id']
                    if not temp1:
                        break
        # ############ 处理菜单和菜单之间的等级关系 ############
        result = []
        for row in all_menu_list:
            pid = row['parent_id']
            if pid:
                all_menu_dict[pid]['child'].append(row)
            else:
                result.append(row)
    
    
        ##################### 结构化处理结果 #####################
        for row in result:
            print(row['caption'],row['status'],row['opened'],row)
    
    
        def menu_tree(menu_list):
            tpl1 = """
            <div class='menu-item'>
                <div class='menu-header'>{0}</div>
                <div class='menu-body {2}'>{1}</div>
            </div>
            """
            tpl2 = """
            <a href='{0}' class='{1}'>{2}</a>
            """
    
            menu_str = ""
            for menu in menu_list:
                if not menu['status']:
                    continue
                # menu: 菜单,权限(url)
                if menu.get('url'):
                    # 权限
                    menu_str += tpl2.format(menu['url'],'active' if menu['opened'] else "",menu['caption'])
                else:
                    # 菜单
                    if menu['child']:
                        child_html = menu_tree(menu['child'])
                    else:
                        child_html = ""
                    menu_str += tpl1.format(menu['caption'], child_html,"" if menu['opened'] else 'hide')
    
            return menu_str
        menu_html = menu_tree(result)
        return menu_html
    
    
    # simple_tag
    def css():
        v = """
            <style>
            .hide{
                display: none;
            }
            .menu-body{
                margin-left: 20px;
            }
            .menu-body a{
                display: block;
            }
            .menu-body a.active{
                color: red;
            }
        </style>
            """
        return v
    
    # simple_tag
    def js():
        v = """
            <script>
            $(function(){
    
                $('.menu-header').click(function(){
                    $(this).next().removeClass('hide').parent().siblings().find('.menu-body').addClass('hide');
    
                })
    
            })
        </script>
        """
        return v
    service.py

    a. 以后调用 

    #自定义的中间件加入到settings
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'rbac.middleware.md.RbacMiddleware',    
    ]
    settings.py
    #后端
    from rbac import service
      
    1. 用户登录后,拿到用户的ID,调用permission_session()函数(函数代码还没写)
       函数获取用户角色的权限,格式如:
       “”“
        user_permission_dict = {
            '/ah-index.html': ["GET","POST","DEL","Edit"],
            '/order.html':  ["GET","POST","DEL","Edit"],
            '/index-(d+).html':  ["GET","POST","DEL","Edit"],
        }
       ”“”
      
        def login():
          permission_session(用户ID,request)
          return .....
      
    2.setting中加入中间件,如上
      
      
    3.#获取菜单
        current_url= request.pathinfo
        menu_list = service.menu(用户ID,current_url)
      
    4.尽量用simple_tag
        css = servicr.css()
        js = servicr.js()
      
    5.前端
      
        {{ css|safe }}
        {{ menu_list|safe }}
        {{ js|safe }}  
    

    代码下载地址:http://files.cnblogs.com/files/luchuangao/rbac.zip

    生产环境使用

    rbac组件完整版下载地址:http://files.cnblogs.com/files/luchuangao/rbac%E5%AE%8C%E6%95%B4%E7%89%88.zip

    a. RBAC原理:

    原理:
        1. 简单管理
            角色单一,无需使用权限管理
    
        2. 角色多管理(权限)
            a. 登录
                session放置用户信息(检测是否已经登录)
                session放置权限信息(检测是否有权访问)
                    {
                        '/index.html':[GET,EDIT],
                        '/order.html':[GET,EDIT],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                        '/xxx.html':[GET,EDIT...],
                    }
                    
                session放置菜单权限信息(用于生成动态多级菜单)
                
            b. 访问网站其他功能: http://www.baiuc.om/xxx.hmtl
                - 获取当前访问的URL, request.path_info
                - 
                        /xxx.hmtl?md=get
                    匹配1
                        /xxx.hmtl
                        session放置权限信息(检测是否有权访问)
                        {
                            '/index.html':[GET,EDIT],
                            '/order.html':[GET,EDIT],
                            '/xxx.html':[GET,EDIT...],
                        }
                        
                    匹配2
                        /xxx.hmtl
                        session放置权限信息(检测是否有权访问)
                        {
                            '/index.html':[GET,EDIT],
                            '/order.html':[GET,EDIT],
                            '/xxx.html':[GET,EDIT...],
                        }
                    
                    request.permission_code = "EDIT"
                    request.permission_code_list = [GET,EDIT...]
                    
                    
                    PS: 中间件实现
                    
            c. 视图函数
            
                    def xxx(request):
                        request.permission_code = "EDIT"              # 业务逻辑的编写
                        request.permission_code_list = [GET,EDIT...]  # 前端显示功能按钮
                        
            d. 模板
            
            
            e. 创建动态菜单【多级菜单】
                    session中获取菜单权限信息(用于生成动态多级菜单)
                        - 当前用户权限
                        - 所有菜单
                    1. 权限挂到菜单上
                    2. 菜单父子关系处理
                    3. 递归生成菜单
                    
                    辅助:
                        css
                        js
                        
                    
                    推荐:simple_tag
            
        
        
    使用:【详细见README】
        1. 导入rbac
            -- 中间件
            - service
            - simple_tag
            
        2. 注册app
        
        3. 用户登录
              初始化权限信息: service.initail_permission(request,user_id)
              
              
        4. settings中配置中间件
        
        5. {% rbac_menu reqeust %}
                
            
        其他配置:
            ...
    RBAC角色管理原理及使用

    b. 应用实例

    具体功能:
    	临时工:
    		报障单     trouble.html
    			查看列表 	look
    			查看详细 	detail
    	
    	普通员工:
    		报障单     trouble.html
    			创建   		post
    			删除   		del
    			修改   		edit
    			查看列表 	look
    			查看详细 	detail
    		
    	运维人员:
    		报账单
    		解决报障单 trouble-kill.html
    		
    	总监:
    		报障单
    		解决报障单
    		报表       report.html
    

    报障系统示例代码:http://files.cnblogs.com/files/luchuangao/rbacdemo.zip

    制作报表参考:制作报表工具

  • 相关阅读:
    [ZJOI2007]仓库建设(斜率dp优化)
    [HNOI2008]玩具装箱toy(斜率优化dp)
    2019牛客暑期多校训练营(第十场)F-Popping Balloons
    2019牛客暑期多校训练营(第十场)B-Coffee Chicken
    子集的生成—二进制枚举
    2019牛客暑期多校训练营(第九场)D-Knapsack Cryptosystem(思维+子集和)
    2019牛客暑期多校训练营(第九场) E-All men are brothers(并查集+组合数学)
    字符串的最小表示法
    2019牛客暑期多校训练营(第八场)
    [HDU4734] 不要62(数位dp入门)
  • 原文地址:https://www.cnblogs.com/luchuangao/p/7229163.html
Copyright © 2011-2022 走看看