zoukankan      html  css  js  c++  java
  • 权限管理——版本2

    权限管理——版本2 

    1.完成目标

     菜单相关:
        [
            {'menu_id':1,'menu_title':'菜单1','title':'用户列表','url':'/userinfo/'},
            {'menu_id':1,'menu_title':'菜单1','title':'订单列表','url':'/order/'},
            {'menu_id':2,'menu_title':'菜单2','title':'xxx列表','url':'/xxx/'},
            {'menu_id':3,'menu_title':'菜单2','title':'aaa列表','url':'/aaa/'},
        ]
    
        菜单1
            用户管理
    
        菜单2
            订单管理
    
        分级,默认展开选中。
    
        构建数据结构:
            {
                1: {
                        'menu_id': 1,
                        'menu_title': '菜单一',
                        'active': None,
                        'children': [
                                {'title': '订单列表', 'url': '/order/', 'active': None}
                            ]
                        }
                2: {
                    'menu_id': 2,
                    'menu_title': '菜单二',
                    'active': True,
                    'children': [
                            {'title': '用户列表', 'url': '/userinfo/', 'active': True}
                        ]
                    },
    
            }
        小结:  菜单相关的数据结构,还需要和当前请求的url匹配,匹配成功,actice为True。
                active有两个操作: 1.目标是否变红   2.目标是否展开或缩小。

    5.从构建数据结构传过来的数据格式变了: 做了一个settings配置名,改以下就不需要每个地方都改。
    6.循环数据,拿字典里面的key,value,字典套字典,要学会取值。
    7.为了让视图知道codes,我们还需要取codes。
    8.把生成菜单的标签放到simple_tag里load就可以了
    9.扩展一个inclusion_tag自定义页面的功能,后面只需要跟一个页面。

    结果实例图:

      

    2.代码

    1.app01/views.py

    from django.shortcuts import render,redirect,HttpResponse
    from rbac import models
    from rbac.service.init_permission import init_permission
    from django.conf import settings
    import re
    
    
    def login(reqeust):
        if reqeust.method == 'GET':
            return  render(reqeust,'login.html')
        else:
            user = reqeust.POST.get('user')
            pwd = reqeust.POST.get('pwd')
            print(reqeust.POST)
            user = models.User.objects.filter(username=user,password=pwd).first()
            print(user)
            if not user:
                return render(reqeust,'login.html')
            init_permission(user,reqeust)
            print(111)
            return redirect('/index/')
    
    
    def index(request):
        print(222)
        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):
        print(request.permisstion_code_list)
        page_permission = BasePagePermission(request.permisstion_code_list)
        data_list = [
            {'id':1,'name':'xxx1'},
            {'id':2,'name':'xxx2'},
            {'id':3,'name':'xxx3'},
            {'id':4,'name':'xxx4'},
            {'id':5,'name':'xxx5'},
        ]
    
        menu_list = request.session[settings.PERMISSTION_MENU_KEY]
    
        return render(request,'userinfo.html',{'data_list':data_list,'page_permission':page_permission})
    
    
    
    
    def userinfo_add(request):
        page_permission = BasePagePermission(request.permisstion_code_list)
        return HttpResponse('添加用户页面')
    
    
    class OrderPagePermission(BasePagePermission):
        def has_report(self):
            if 'report' in self.code_list:
                return True
    
    
    def order(request):
        order_permission = OrderPagePermission(request.permisstion_code_list)
        return render(request, 'order.html')
    views.py

    2.settings:

    STATIC_URL = '/static/'
    
    PERMISSTION_URL_DICT = 'permissions_url_dict'
    PERMISSTION_MENU_KEY = 'asdasdasdada'
    VALID_URL = [
        '/login/',
        '/admin.*/'
    
    ]

    3.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)
    
    
    ]

    4.rbac/middlewares/rbac.py

    import re
    from permission import settings
    
    from django.shortcuts import redirect,HttpResponse
    
    
    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().不能request.session[],因为可能没数据。
               3.设置白名单,获取到白名单的放行数据,和用户所拥有的权限url,匹配。 如果匹配,就不需要经过权限的检查。
               4.当用户访问了组的列表页面后,就应该知道他在这个组里还有什么权限。
                    -1.分组: 1可以是用户组, 2是订单组
                    -2.不当是用户列表页面需要知道他的所有权限,其它页面也应该知道。使用codes来获取。
                    -3. 以上这样设置,不管什么页面都能知道所有的权限url,找到codes就可以。
                            list = {
                            1:{
                                'codes':['list','add','edit','del']
                                'urls':[
                                /userinfo/
                                /userinfo/add/
                                /userinfo/edit/(d+)/
                                /userinfo/del/(d+)/
                                ]
                            }
                        }
                5.从构建数据结构传过来的数据格式变了: 做了一个settings配置名,改以下就不需要每个地方都改。
                6.循环数据,拿字典里面的key,value,字典套字典,要学会取值。
                7.为了让视图知道codes,我们还需要取codes。
                8.把生成菜单的标签放到simple_tag里load就可以了
                9.扩展一个inclusion_tag自定义页面的后面只需要跟一个页面。
                 '''
            current_url = request.path_info
            
            for url in settings.VALID_URL:
                if re.match(url,current_url):
                    print(url,current_url)
                    return None
    
    
            permission_dict = request.session.get(settings.PERMISSTION_URL_DICT)  # 拿到url格式的数据
            if not permission_dict:
                return redirect('/login/')
            flag = False
            for group_id,code_url in permission_dict.items():  # 用in不行,含正则的url使用in会匹配不了,所要要用正则:re.match
                for db_url  in code_url['urls']:
                    regax =  '^{0}$'.format(db_url) #加上起止符,绝对匹配。
                    if re.match(regax, current_url):  # 如果匹配成功,就已等
                        request.permisstion_code_list = code_url['codes']   #取到codes列表,存到request里
                        flag = True
                        break
                if flag:
                    break
            if not flag:
                return HttpResponse('无权访问')
    rbac.py

    5.rbac/service/init_permission.py

    from django.conf import  settings
    
    def init_permission(user,request):
        '''
        初始化权限信息,把权限url放到session。
        :param user:
        :param request:
        :return:
    
        list = {
        1:{
            'codes':['list','add','edit','del']
            'urls':[
            /userinfo/
            /userinfo/add/
            /userinfo/edit/(d+)/
            /userinfo/del/(d+)/
            ]
        }
    }
    
        菜单相关:
        [
            {'menu_id':1,'menu_title':'菜单1','title':'用户列表','url':'/userinfo/'},
            {'menu_id':1,'menu_title':'菜单1','title':'订单列表','url':'/order/'},
            {'menu_id':2,'menu_title':'菜单2','title':'xxx列表','url':'/xxx/'},
            {'menu_id':3,'menu_title':'菜单2','title':'aaa列表','url':'/aaa/'},
        ]
    
        菜单1
            用户管理
    
        菜单2
            订单管理
    
        分级,默认展开选中。
    
        构建数据结构:
            {
                1: {
                        'menu_id': 1,
                        'menu_title': '菜单一',
                        'active': None,
                        'children': [
                                {'title': '订单列表', 'url': '/order/', 'active': None}
                            ]
                        }
                2: {
                    'menu_id': 2,
                    'menu_title': '菜单二',
                    'active': True,
                    'children': [
                            {'title': '用户列表', 'url': '/userinfo/', 'active': True}
                        ]
                    },
    
            }
        小结:  菜单相关的数据结构,还需要和当前请求的url匹配,匹配成功,actice为True。
                active有两个操作: 1.目标是否变红   2.目标是否展开或缩小。
        '''
        permission_list2 = user.roles.values('permissions__title', #权限名称
                                             'permissions__url',   #权限url
                                             'permissions__is_menu', #权限是否是菜单
                                             'permissions__codes',  #权限的codes
                                             'permissions__group_id',   #组id
                                             'permissions__group__menu_id', #菜单id
                                             'permissions__group__menu__title' #菜单名称
                                             ).distinct()
        menu_list = []
        #去掉不是菜单的url
        for item in permission_list2:
            if not item['permissions__is_menu']:
                continue
            tpl = {
                'menu_id':item['permissions__group__menu_id'],
                'menu_title':item['permissions__group__menu__title'],
                'title':item['permissions__title'],
                'url':item['permissions__url'],
                'active':False
            }
            menu_list.append(tpl)
        request.session[settings.PERMISSTION_MENU_KEY] = menu_list
    
    
        #权限相关
        result = {}
        for item in  permission_list2:
            group_id = item['permissions__group_id']
            code = item['permissions__codes']
            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.PERMISSTION_URL_DICT] = result
    
        #拿到用户请求url,和session做对比,如果在,可访问,不在,一边去。
    View Code

    6.rbac/static/rabc/rbac.css

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

    7..rbac/static/rabc/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')
            }
        })
    
    
    });

    8.rbac/templatetags/rbac.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.PERMISSTION_MENU_KEY]
        current_url = request.path_info
        result = {}
        for item in menu_list:
            url = item['url']
            print(url)
            regex = '^{0}$'.format(url)
            active = False
            if re.match(regex,current_url):
                active = True
            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':menu_id,
                    'menu_title':item['menu_title'],
                    'active': active,
                    'children': [
                        {'title': item['title'], 'url': item['url'], 'active': active},
                    ]
                }
        return {'menu_dict':result}
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
                
            
    View Code

    9.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 %}
  • 相关阅读:
    PAT (Advanced Level) Practice 1100 Mars Numbers (20分)
    PAT (Advanced Level) Practice 1107 Social Clusters (30分) (并查集)
    PAT (Advanced Level) Practice 1105 Spiral Matrix (25分)
    PAT (Advanced Level) Practice 1104 Sum of Number Segments (20分)
    PAT (Advanced Level) Practice 1111 Online Map (30分) (两次迪杰斯特拉混合)
    PAT (Advanced Level) Practice 1110 Complete Binary Tree (25分) (完全二叉树的判断+分享致命婴幼儿错误)
    PAT (Advanced Level) Practice 1109 Group Photo (25分)
    PAT (Advanced Level) Practice 1108 Finding Average (20分)
    P6225 [eJOI2019]异或橙子 树状数组 异或 位运算
    P4124 [CQOI2016]手机号码 数位DP
  • 原文地址:https://www.cnblogs.com/zhongbokun/p/8538711.html
Copyright © 2011-2022 走看看