• 权限管理——版本3


    权限管理——版本3

    1.目标

      -解决版本的BUG,即,当我们点击添加/删除/编辑时,菜单的首页都会缩小,按理说:不应该缩小。

      -看看最终的实现:

        

        点击添加之后,注意看左边的菜单管理,按理是不应该缩小的,但是之前的版本2是会缩小的,所以需要解决这个问题。

        

        

    解决方案思路:

      

    解决:
            1.找到当前点击进入的url,找到这个url的组,让这个组默认选中菜单就可以。
                - 请求url:request.path_info
                - 所有的url; .....  
                -以上两个一一匹配,成功之后,找到组id,通过组id找到当前组里的"is_menu"=True的这条记录,
                在它后面加个active = True为默认被选中。然后需要再一次循环,把is_menu为True取出来,让这两生成菜单就可以了。
                前提:一组一个菜单
                
            2.修改数据库的记录。
                1.方法1:在权限表加一个组内菜单的字段,自关联。null 就为菜单
                    /userinfo/      list     null     组1
                    /userinfo/add     add     1          组1
                    /userinfo/edit     edit     1          组1
                    /userinfo/del     del     1          组1
                    
                    /order/            list    null    组2
                    /order/add        add        5        组2
                    /order/edit        edit    5        组2
                    /order/del        del        5        组2
                    
                2.方法2:
                    设一个菜单字典:
                        menu_dict = {
                            1:{'id':1,'title':'用户列表','url':'/userinfo/','menu_gp_id':None,'menu_id':1,'menu_title':'菜单管理',active=True}
                            5:{'id':5,'title':'订单列表','url':'/order/','menu_gp_id':None,'menu_id':2,'menu_title':'订单管理'}
                        }
                    
                        current_url = request.path_info
                        for item in menu_list:
                            url = item['url']
                            regex = '^{0}$'format(url)
                            if re.match(regex,current_url):
                                menu_gp_id = item['menu_gp_id']
                                if not menu_gp_id:
                                    #给自己加active = True,下面两个方式都可以用,因为用的是同一个引用。
                                        item['active'] = True
                                        menu_dict[item]['id']['active']=True
                                else:
                                    menu_dict[menu_gp_id]['active'] = True

    2.代码

    app01/views.py:

    import re
    
    from django.shortcuts import render,redirect,HttpResponse
    from django.conf import settings
    from rbac import models
    from rbac.service.init_permission import init_permission
    def login(request):
        if request.method == "GET":
            return render(request,'login.html')
        else:
            user = request.POST.get('user')
            pwd = request.POST.get('pwd')
            user = models.User.objects.filter(username=user,password=pwd).first()
            print(request.POST)
            if not user:
                return render(request, 'login.html')
            init_permission(user,request)
            return redirect('/index/')
    
    
    def index(request):
    
        return HttpResponse('欢迎登录')
    
    
    class BasePagePermission(object):
        def __init__(self,code_list):
            self.code_list = code_list
    
        def has_add(self):
            if "add" in self.code_list:
                return True
    
        def has_edit(self):
            if 'edit' in self.code_list:
                return True
        def has_del(self):
            if 'del' in self.code_list:
                return True
    
    def userinfo(request):
        page_permission = BasePagePermission(request.permission_code_list)
        data_list = [
            {'id':1,'name':'xxx1'},
            {'id':2,'name':'xxx2'},
            {'id':3,'name':'xxx3'},
            {'id':4,'name':'xxx4'},
            {'id':5,'name':'xxx5'},
        ]
    
        return render(request,'userinfo.html',{'data_list':data_list,'page_permission':page_permission})
    
    
    def userinfo_add(request):
        page_permission = BasePagePermission(request.permission_code_list)
        return render(request, 'userinfo_add.html', { 'page_permission': page_permission})
    
    
    
    class OrderPagePermission(BasePagePermission):
    
        def has_report(self):
            if 'report' in self.code_list:
                return True
    
    def order(request):
        order_permission = OrderPagePermission(request.permission_code_list)
    
    
        return render(request,'order.html')
    
    def order_add(request):
        return HttpResponse('添加订单页面')
    View Code

    settings.py:

    urls.py:

    from django.conf.urls import url
    from django.contrib import admin
    from rbac import views
    from app01 import views as app01_views
    urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^test/', views.test),
    url(r'^login/', app01_views.login),
    url(r'^index/', app01_views.index),
    url(r'^userinfo/$', app01_views.userinfo),
    url(r'^userinfo/add/$', app01_views.userinfo_add),
    url(r'^order/$', app01_views.order),
    url(r'^order/add/$', app01_views.order_add),
    ]

     rbacmiddlewares bac.py:

    import re
    
    from django.shortcuts import redirect,HttpResponse
    from django.conf import settings
    
    class MiddlewareMixin(object):
        def __init__(self, get_response=None):
            self.get_response = get_response
            super(MiddlewareMixin, self).__init__()
    
        def __call__(self, request):
            response = None
            if hasattr(self, 'process_request'):
                response = self.process_request(request)
            if not response:
                response = self.get_response(request)
            if hasattr(self, 'process_response'):
                response = self.process_response(request, response)
            return response
    
    
    class RbacMiddleware(MiddlewareMixin):
    
        def process_request(self,request):
            # 1. 获取当前请求的URL
            # request.path_info
            # 2. 获取Session中保存当前用户的权限
            # request.session.get("permission_url_list')
            current_url = request.path_info
    
            # 当前请求不需要执行权限验证
            for url in settings.VALID_URL:
                if re.match(url,current_url):
                    return None
    
            permission_dict = request.session.get(settings.PERMISSION_URL_DICT_KEY)
            if not permission_dict:
                return redirect('/login/')
    
            flag = False
            for group_id,code_url in permission_dict.items():
    
                for db_url in code_url['urls']:
                    regax = "^{0}$".format(db_url)
                    if re.match(regax, current_url):
                        request.permission_code_list = code_url['codes']
                        flag = True
                        break
                if flag:
                    break
    
            if not flag:
                return HttpResponse('无权访问')
    View Code

    rbacserviceinit_permission.py

    from django.conf import settings
    
    
    def init_permission(user,request):
        """
        初始化权限信息,获取权限信息并放置到session中。
        :param user:
        :param request:
        :return:
        """
        permission_list = user.roles.values('permissions__id',
                                            'permissions__title',              # 用户列表
                                            'permissions__url',
                                            'permissions__code',
                                            'permissions__menu_gp_id',         # 组内菜单ID,Null表示是菜单
                                            'permissions__group_id',
                                            'permissions__group__menu_id',     # 菜单ID
                                            'permissions__group__menu__title',#  菜单名称
                                            ).distinct()
    
        # 菜单相关(以后再匹配)
        sub_permission_list = []
        for item in permission_list:
            tpl = {
                'id':item['permissions__id'],
                'title':item['permissions__title'],
                'url':item['permissions__url'],
                'menu_gp_id':item['permissions__menu_gp_id'],
                'menu_id':item['permissions__group__menu_id'],
                'menu_title':item['permissions__group__menu__title'],
            }
            sub_permission_list.append(tpl)
        request.session[settings.PERMISSION_MENU_KEY] = sub_permission_list
    
        # 权限相关
        result = {}
        for item in  permission_list:
            group_id = item['permissions__group_id']
            code = item['permissions__code']
            url = item['permissions__url']
            if group_id in result:
                result[group_id]['codes'].append(code)
                result[group_id]['urls'].append(url)
            else:
                result[group_id] = {
                    'codes':[code,],
                    'urls':[url,]
                }
    
        request.session[settings.PERMISSION_URL_DICT_KEY] = result
    View Code

     rbac.css

    .item-permission{
        padding: 3px 10px;
    }
    .item-permission a{
        display: block;
    }
    .item-permission a.active{
        color: red;
    }
    .hide{
        display: none;
    }

    rbac.js

    /**
     * Created by Administrator on 2017/11/8.
     */
     $(function () {
        $('.item-title').click(function () {
            if($(this).next().hasClass('hide')){
                $(this).next().removeClass('hide')
            }else{
                $(this).next().addClass('hide')
            }
        })
    
    
    });

    rbac emplatetags bac.py

    import re
    from django.template import Library
    from django.conf import settings
    register = Library()
    
    @register.inclusion_tag("xxxxx.html")
    def menu_html(request):
        """
        去Session中获取菜单相关信息,匹配当前URL,生成菜单
        :param request:
        :return:
        """
        menu_list = request.session[settings.PERMISSION_MENU_KEY]
        current_url = request.path_info
    
        menu_dict = {}
        for item in menu_list:
            if not item['menu_gp_id']:
                menu_dict[item['id']] = item
    
        for item in menu_list:
            regex = "^{0}$".format(item['url'])
            if re.match(regex,current_url):
                menu_gp_id = item['menu_gp_id']
                if menu_gp_id:
                    menu_dict[menu_gp_id]['active'] = True
                else:
                    menu_dict[item['id']]['active'] = True
    
        result = {}
        for item in menu_dict.values():
            active = item.get('active')
            menu_id = item['menu_id']
            if menu_id in result:
                result[menu_id]['children'].append({ 'title': item['title'], 'url': item['url'],'active':active})
                if active:
                    result[menu_id]['active'] = True
            else:
                result[menu_id] = {
                    'menu_id':item['menu_id'],
                    'menu_title':item['menu_title'],
                    'active':active,
                    'children':[
                        { 'title': item['title'], 'url': item['url'],'active':active}
                    ]
                }
    
        return {'menu_dict':result}
    View Code

    rbacmodels.py

    from django.db import models
    
    class Menu(models.Model):
        """
        菜单组
        """
        title = models.CharField(max_length=32)
    
    
    class Group(models.Model):
        """
        权限组
        """
        caption = models.CharField(verbose_name='组名称',max_length=16)
        menu = models.ForeignKey(verbose_name='所属菜单',to='Menu',default=1)
    
    
    class Permission(models.Model):
        """
        权限表
        """
        title = models.CharField(verbose_name='标题',max_length=32)
        url = models.CharField(verbose_name="含正则URL",max_length=64)
    
        menu_gp = models.ForeignKey(verbose_name='组内菜单',to='Permission',null=True,blank=True,related_name='x1')
    
        code = models.CharField(verbose_name="代码",max_length=16)
        group = models.ForeignKey(verbose_name='所属组',to="Group")
    
        class Meta:
            verbose_name_plural = "权限表"
    
        def __str__(self):
            return self.title
    
    class User(models.Model):
        """
        用户表
        """
        username = models.CharField(verbose_name='用户名',max_length=32)
        password = models.CharField(verbose_name='密码',max_length=64)
        email = models.CharField(verbose_name='邮箱',max_length=32)
    
        roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
    
        class Meta:
            verbose_name_plural = "用户表"
    
        def __str__(self):
            return self.username
    
    class Role(models.Model):
        """
        角色表
        """
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
        class Meta:
            verbose_name_plural = "角色表"
    
        def __str__(self):
            return self.title
    View Code

    layout.html:

    {% load rbac %}
    <!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/rbac/rbac.css" />
        <title>Title</title>
    </head>
    <body>
            <div style="float: left; 20%;height: 500px;background-color: #dddddd">
                {% menu_html request %}
            </div>
            <div style="float: left; 80%">
                {% block content %}{% endblock %}
            </div>
    
                <script src="/static/jquery-3.2.1.min.js"></script>
                <script src="/static/rbac/rbac.js"></script>
    
    </body>
    </html>
    View Code

    xxxxx.html:

    {% for k,item in menu_dict.items %}
        <div class="item">
            <div class="item-title">{{ item.menu_title }}</div>
            {% if item.active %}
                <div class="item-permission">
            {% else %}
                <div class="item-permission hide">
            {% endif %}
                {% for v in item.children %}
    
                    {% if v.active %}
                        <a href="{{ v.url }}" class="active">{{ v.title }}</a>
                    {% else %}
                        <a href="{{ v.url }}">{{ v.title }}</a>
                    {% endif %}
    
                {% endfor %}
            </div>
        </div>
    {% endfor %}
    View Code
  • 相关阅读:
    Java自学-数字与字符串 字符串
    Java自学-数字与字符串 格式化输出
    Java自学-数字与字符串 数学方法
    Java自学-数字与字符串 字符串转换
    Java自学-数字与字符串 装箱和拆箱
    Java自学-接口与继承 UML图
    Mysql优化系列之查询优化干货1
    Mysql优化系列之查询性能优化前篇3(必须知道的几个事实)
    Mysql优化系列之查询性能优化前篇2
    第二十二篇:Spring简单定时任务
  • 原文地址:https://www.cnblogs.com/zhongbokun/p/8538862.html
Copyright © 2020-2023  润新知