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 %}
  • 相关阅读:
    JS控制的几种页面跳转方式和传值
    文件管理
    文件:文件和文件夹
    上传文件
    购物车的例子
    使用ajax登录格式
    ajax 另外两种返回类型(json xml)
    省级三级联动
    thinkPHP--SQL连贯操作
    thinkPHP-空操作
  • 原文地址:https://www.cnblogs.com/zhongbokun/p/8538711.html
Copyright © 2011-2022 走看看