• CRM+RBAC


    权限系统的应用

    权限系统的应用
        1. 拷贝rbac 到新项目中
        
        2. 注册rbac APP 以及配置信息
        
            PERMISSION_SESSION_KEY = 'permissions'
            MENU_SESSION_KEY = 'menus'
            WHITE_URL_LIST = [
                r'/login/$',
                r'^/logout/$',
                r'^/reg/$',
                r'^/admin/.*',
            ]
        3. 数据库迁移 
            删除原有的迁移文件的记录
            执行命令
            
        4. 在根目录下的urls.py中添加rbac的相关URL
            # 权限的url
            url(r'rbac/', include('rbac.urls',namespace='rbac')),
            
        5. 录入权限信息
            - 角色管理
            - 菜单管理
            - 权限管理
                - 录入原系统的URL
                - 录入rbac的URL
                    - 权限批量操作的视图中ignore_namespace_list中去掉rbac
                         # 获取路由系统中所有URL
                         router_dict = get_all_url_dict(ignore_namespace_list=['admin'])
                
        6. 分配权限
            - 用户关联
                from rbac.models import User
                user = models.OneToOneField(User, null=True, blank=True)
                
            - 给用户分角色
            - 给角色分权限
            
        7. 登录应用权限
            - 登录成功后执行init_permission(request, obj) 
            - 修改init_permission
                user   ——》 user.user 
            - 应用权限校验中间件
                 'rbac.middlewares.rbac.PermissionMiddleware',
                 
                 
        8. 应用二级菜单和面包屑导航
            注意模板 layout
                有block  css  js content 
                
            - 二级菜单
                    <link rel="stylesheet" href="{% static 'css/menu.css' %}">
                    {% load rbac %}
                    {% menu request %}
                    <script src="{% static 'js/menu.js' %}"></script>
                    
            - 面包屑导航
                {% breadcrumb request %}
                
        9. 权限控制到按钮级别
            {% load rbac %}
    
            {% if request|has_permission:'add_customer' %}
                <a href="{% url 'add_customer' %}?{{ query_params }}" class="btn btn-primary btn-sm">添加</a>
            {% endif %}

    中间件初始化

    from django.conf import settings
    from django.shortcuts import HttpResponse
    
    def init_permission(request, user):
        # 1. 查当前登录用户拥有的权限
        try:
            permission_query = user.user.roles.filter(permissions__url__isnull=False).values(
                'permissions__url',
                'permissions__title',
                'permissions__id',
                'permissions__name',
                'permissions__parent_id',
                'permissions__parent__name',
                'permissions__menu_id',
                'permissions__menu__title',
                'permissions__menu__icon',
                'permissions__menu__weight',
            ).distinct()
        except Exception as e:
            return HttpResponse('请联系管理员:电话:110')
            
        
        # 存放权限信息
        permission_dict = {}
        
        # 存放菜单信息
        
        menu_dict = {}
        
        for item in permission_query:
            permission_dict[item['permissions__name']] = {'url': item['permissions__url'],
                                                          'id': item['permissions__id'],
                                                          'pid': item['permissions__parent_id'],
                                                          'pname': item['permissions__parent__name'],
                                                          'title': item['permissions__title']}
            
            menu_id = item.get('permissions__menu_id')
            
            if not menu_id:
                continue
            
            if menu_id not in menu_dict:
                menu_dict[menu_id] = {
                    'title': item['permissions__menu__title'],
                    'icon': item['permissions__menu__icon'],
                    'weight': item['permissions__menu__weight'],
                    'children': [
                        {'title': item['permissions__title'], 'url': item['permissions__url'],
                         'id': item['permissions__id'], 'pid': item['permissions__parent_id']}
                    ]
                }
            else:
                menu_dict[menu_id]['children'].append(
                    {'title': item['permissions__title'], 'url': item['permissions__url'], 'id': item['permissions__id'],
                     'pid': item['permissions__parent_id']})
        
        # # 2. 将权限信息写入到session
        request.session[settings.PERMISSION_SESSION_KEY] = permission_dict
        
        # 将菜单信息写入到session
        request.session[settings.MENU_SESSION_KEY] = menu_dict
    init_permission.py

    视图

    from django.shortcuts import render, HttpResponse, redirect, reverse
    from rbac import models
    from rbac.forms import *
    from django.db.models import Q
    from rbac.server.routes import get_all_url_dict
    
    
    def role_list(request):
        all_roles = models.Role.objects.all()
        return render(request, 'rbac/role_list.html', {"all_roles": all_roles})
    
    
    def role(request, edit_id=None):
        obj = models.Role.objects.filter(id=edit_id).first()
        form_obj = RoleForm(instance=obj)
        if request.method == 'POST':
            form_obj = RoleForm(request.POST, instance=obj)
            if form_obj.is_valid():
                form_obj.save()
                return redirect(reverse('rbac:role_list'))
        
        return render(request, 'rbac/form.html', {'form_obj': form_obj})
    
    
    def del_role(request, del_id):
        models.Role.objects.filter(id=del_id).delete()
        return redirect(reverse('rbac:role_list'))
    
    
    # 菜单信息  权限信息
    def menu_list(request):
        all_menu = models.Menu.objects.all()
        
        mid = request.GET.get('mid')
        
        if mid:
            permission_query = models.Permission.objects.filter(Q(menu_id=mid) | Q(parent__menu_id=mid))
        else:
            permission_query = models.Permission.objects.all()
        
        all_permission = permission_query.values('id', 'url', 'title', 'name', 'menu_id', 'parent_id', 'menu__title')
        
        all_permission_dict = {}
        
        for item in all_permission:
            menu_id = item.get('menu_id')
            if menu_id:
                item['children'] = []
                all_permission_dict[item['id']] = item
        
        for item in all_permission:
            pid = item.get('parent_id')
            
            if pid:
                all_permission_dict[pid]['children'].append(item)
        
        print(all_permission_dict)
        
        return render(request, 'rbac/menu_list.html',
                      {"all_menu": all_menu, 'all_permission_dict': all_permission_dict, 'mid': mid})
    
    
    def menu(request, edit_id=None):
        obj = models.Menu.objects.filter(id=edit_id).first()
        form_obj = MenuForm(instance=obj)
        if request.method == 'POST':
            form_obj = MenuForm(request.POST, instance=obj)
            if form_obj.is_valid():
                form_obj.save()
                return redirect(reverse('rbac:menu_list'))
        
        return render(request, 'rbac/form.html', {'form_obj': form_obj})
    
    
    def permission(request, edit_id=None):
        obj = models.Permission.objects.filter(id=edit_id).first()
        form_obj = PermissionForm(instance=obj)
        if request.method == 'POST':
            form_obj = PermissionForm(request.POST, instance=obj)
            if form_obj.is_valid():
                form_obj.save()
                return redirect(reverse('rbac:menu_list'))
        
        return render(request, 'rbac/form.html', {'form_obj': form_obj})
    
    
    def del_permission(request, del_id):
        models.Permission.objects.filter(id=del_id).delete()
        return redirect(reverse('rbac:menu_list'))
    
    
    from django.forms import modelformset_factory, formset_factory
    
    
    def multi_permissions(request):
        """
        批量操作权限
        :param request:
        :return:
        """
        
        post_type = request.GET.get('type')
        
        # 更新和编辑用的
        FormSet = modelformset_factory(models.Permission, MultiPermissionForm, extra=0)
        # 增加用的
        AddFormSet = formset_factory(MultiPermissionForm, extra=0)
        
        permissions = models.Permission.objects.all()
        
        # 获取路由系统中所有URL
        router_dict = get_all_url_dict(ignore_namespace_list=['admin'])
        
        # 数据库中的所有权限的别名
        permissions_name_set = set([i.name for i in permissions])
        
        # 路由系统中的所有权限的别名
        router_name_set = set(router_dict.keys())
    
        add_name_set = router_name_set - permissions_name_set
        add_formset = AddFormSet(initial=[row for name, row in router_dict.items() if name in add_name_set])
        
        if request.method == 'POST' and post_type == 'add':
            add_formset = AddFormSet(request.POST)
            if add_formset.is_valid():
                print(add_formset.cleaned_data)
                permission_obj_list = [models.Permission(**i) for i in add_formset.cleaned_data]
                
                query_list = models.Permission.objects.bulk_create(permission_obj_list)
                
                for i in query_list:
                    permissions_name_set.add(i.name)
                add_formset = AddFormSet()
            else:
                print(add_formset.errors)
                
            
        
        
        
        del_name_set = permissions_name_set - router_name_set
        del_formset = FormSet(queryset=models.Permission.objects.filter(name__in=del_name_set))
        
        update_name_set = permissions_name_set & router_name_set
        update_formset = FormSet(queryset=models.Permission.objects.filter(name__in=update_name_set))
        
        if request.method == 'POST' and post_type == 'update':
            update_formset = FormSet(request.POST)
            if update_formset.is_valid():
                update_formset.save()
                update_formset = FormSet(queryset=models.Permission.objects.filter(name__in=update_name_set))
        
        return render(
            request,
            'rbac/multi_permissions.html',
            {
                'del_formset': del_formset,
                'update_formset': update_formset,
                'add_formset': add_formset,
            }
        )
    
    
    def distribute_permissions(request):
        """
        分配权限
        :param request:
        :return:
        """
        uid = request.GET.get('uid')
        rid = request.GET.get('rid')
        
        if request.method == 'POST' and request.POST.get('postType') == 'role':
            user = models.User.objects.filter(id=uid).first()
            if not user:
                return HttpResponse('用户不存在')
            user.roles.set(request.POST.getlist('roles'))
        
        if request.method == 'POST' and request.POST.get('postType') == 'permission' and rid:
            role = models.Role.objects.filter(id=rid).first()
            if not role:
                return HttpResponse('角色不存在')
            role.permissions.set(request.POST.getlist('permissions'))
        
        # 所有用户
        user_list = models.User.objects.all()
        
        user_has_roles = models.User.objects.filter(id=uid).values('id', 'roles')
        
        # print(user_has_roles)
        
        user_has_roles_dict = {item['roles']: None for item in user_has_roles}
        
        """
        用户拥有的角色id
        user_has_roles_dict = { 角色id:None }
        """
        
        role_list = models.Role.objects.all()
        
        if rid:
            role_has_permissions = models.Role.objects.filter(id=rid).values('id', 'permissions')
        elif uid and not rid:
            user = models.User.objects.filter(id=uid).first()
            if not user:
                return HttpResponse('用户不存在')
            role_has_permissions = user.roles.values('id', 'permissions')
        else:
            role_has_permissions = []
        
        print(role_has_permissions)
        
        role_has_permissions_dict = {item['permissions']: None for item in role_has_permissions}
        
        """
        角色拥有的权限id
        role_has_permissions_dict = { 权限id:None }
        """
        
        all_menu_list = []
        
        queryset = models.Menu.objects.values('id', 'title')
        menu_dict = {}
        
        """
        
        all_menu_list = [
                {  id:   title :  , children : [
                    { 'id', 'title', 'menu_id', 'children: [
                    'id', 'title', 'parent_id'
                    ]  }
                ] },
                {'id': None, 'title': '其他', 'children': [
                {'id', 'title', 'parent_id'}]}
        ]
        
        menu_dict = {
            菜单的ID: {  id:   title :  , children : [
                { 'id', 'title', 'menu_id', 'children: [
                'id', 'title', 'parent_id'
                ]  }
            ] },
            none:{'id': None, 'title': '其他', 'children': [
            {'id', 'title', 'parent_id'}]}
        }
        """
        
        for item in queryset:
            item['children'] = []  # 放二级菜单,父权限
            menu_dict[item['id']] = item
            all_menu_list.append(item)
        
        other = {'id': None, 'title': '其他', 'children': []}
        all_menu_list.append(other)
        menu_dict[None] = other
        
        root_permission = models.Permission.objects.filter(menu__isnull=False).values('id', 'title', 'menu_id')
        
        root_permission_dict = {}
        
        """
        root_permission_dict = { 父权限的id : { 'id', 'title', 'menu_id', 'children: [
            { 'id', 'title', 'parent_id' }
        ]  }}
        """
        
        for per in root_permission:
            per['children'] = []  # 放子权限
            nid = per['id']
            menu_id = per['menu_id']
            root_permission_dict[nid] = per
            menu_dict[menu_id]['children'].append(per)
        
        node_permission = models.Permission.objects.filter(menu__isnull=True).values('id', 'title', 'parent_id')
        
        for per in node_permission:
            pid = per['parent_id']
            if not pid:
                menu_dict[None]['children'].append(per)
                continue
            root_permission_dict[pid]['children'].append(per)
        
        return render(
            request,
            'rbac/distribute_permissions.html',
            {
                'user_list': user_list,
                'role_list': role_list,
                'user_has_roles_dict': user_has_roles_dict,
                'role_has_permissions_dict': role_has_permissions_dict,
                'all_menu_list': all_menu_list,
                'uid': uid,
                'rid': rid
            }
        )
    rbac/view.py
    幻想毫无价值,计划渺如尘埃,目标不可能达到。这一切的一切毫无意义——除非我们付诸行动。
  • 相关阅读:
    javascript中!=、!==、==、===操作符总结
    轮询、长轮询与Web Socket的前端实现
    C#中Enum用法小结
    浅谈Javascript 中几种克隆(clone)方式
    JS数组sort比较函数
    为Jquery类和Jquery对象扩展方法
    自定义滚动条mCustomScrollbar
    T-SQL 控制流语句
    sql case 用法总结
    Selenium2+python自动化19-单选框和复选框(radiobox、checkbox)【转载】
  • 原文地址:https://www.cnblogs.com/TodayWind/p/13880345.html
Copyright © 2020-2023  润新知