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
视图
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 } )
幻想毫无价值,计划渺如尘埃,目标不可能达到。这一切的一切毫无意义——除非我们付诸行动。