权限的分配
一、权限分配
最终生成页面:
视图函数views.py
主要内容:从数据库中查到相应数据,构建层级结构。
- 一级菜单
- 二级菜单
- 归属二级菜单的子权限
- 二级菜单
def distribute_permissions(request): """ 分配权限 :param request: :return: """ # 用户id uid = request.GET.get('uid') # 角色id rid = request.GET.get('rid') if request.method == 'POST' and request.POST.get('postType') == 'role': # 角色分配 user = 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 = Role.objects.filter(id=rid).first() if not role: return HttpResponse('角色不存在') # 为角色分配权限 role.permissions.set(request.POST.getlist('permissions')) # 获取所有的用户 user_list = User.objects.all() # 当前选中用户所拥有的角色 user_has_roles = User.objects.filter(id=uid).values('id', 'roles') user_has_roles_dict = {item['roles']: None for item in user_has_roles} """ user_has_roles_dict = { 角色的id:None } """ # 所有的角色 role_list = Role.objects.all() if rid: # 查出当前角色所拥有的权限 role_has_permissions = Role.objects.filter(id=rid).values('id', 'permissions') elif uid and not rid: user = User.objects.filter(id=uid).first() if not user: return HttpResponse('用户不存在') # 查出前用户所拥有的角色所对应的权限 role_has_permissions = user.roles.values('id', 'permissions') else: role_has_permissions = [] role_has_permissions_dict = {item['permissions']: None for item in role_has_permissions} """" role_has_permissions_dict = { 权限的id :None } """ all_menu_list = [] """ all_menu_list = [ { 'id', 'title', ‘children' : [ { 'id', 'title', 'menu_id' , 'children': [ {'id', 'title', 'parent_id'} ] } ] }, {'id': None, 'title': '其他', 'children': [ {'id', 'title', 'parent_id'} ]} ] """ queryset = Menu.objects.values('id', 'title') menu_dict = {} """ 需要构成的分级数据结构 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 = 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 = 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/distribute_permissions.html
主要有三块结构,注意数据的转义。数字key变为了字符串类型。
{% extends 'layout.html' %} {% load rbac %} {% block css %} <style> .user-area ul { padding-left: 20px; } .user-area li { cursor: pointer; padding: 2px 0; } .user-area li a { display: block; } .user-area li.active { font-weight: bold; color: red; } .user-area li.active a { color: red; } .role-area tr td a { display: block; } .role-area tr.active { background-color: #f1f7fd; border-left: 3px solid #fdc00f; } .permission-area tr.root { background-color: #f1f7fd; cursor: pointer; } .permission-area tr.root td i { margin: 3px; } .permission-area .node { } .permission-area .node input[type='checkbox'] { margin: 0 5px; } .permission-area .node .parent { padding: 5px 0; } .permission-area .node label { font-weight: normal; margin-bottom: 0; font-size: 12px; } .permission-area .node .children { padding: 0 0 0 20px; } .permission-area .node .children .child { display: inline-block; margin: 2px 5px; } table { font-size: 12px; } .panel-body { font-size: 12px; } .panel-body .form-control { font-size: 12px; } </style> {% endblock %} {% block content %} <div class="luffy-container"> <div class="col-md-3 user-area"> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading"> <i class="fa fa-address-book-o" aria-hidden="true"></i> 用户信息 </div> <div class="panel-body"> <ul> {% for user in user_list %} <li class= {% if user.id|safe == uid %} "active" {% endif %}> <a href="?uid={{ user.id }}">{{ user.name }}</a></li> {% endfor %} </ul> </div> </div> </div> <div class="col-md-3 role-area"> <form method="post"> {% csrf_token %} <input type="hidden" name="postType" value="role"> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading"> <i class="fa fa-book" aria-hidden="true"></i> 角色 {% if uid %} <button type="submit" class="right btn btn-success btn-xs" style="padding: 2px 8px;margin: -3px;"> <i class="fa fa-save" aria-hidden="true"></i> 保存 </button> {% endif %} </div> <div class="panel-body" style="color: #d4d4d4;padding:10px 5px;"> 提示:点击用户后才能为其分配角色 </div> <table class="table"> <thead> <tr> <th>角色</th> <th>选择</th> </tr> </thead> <tbody> {% for role in role_list %} <tr {% if role.id|safe == rid %} class="active" {% endif %}> <td><a href="?{% gen_role_url request role.id %}">{{ role.name }}</a></td> <td> <input type="checkbox" name="roles" value="{{ role.id }}" {% if role.id in user_has_roles_dict %} checked {% endif %} > </td> </tr> {% endfor %} </tbody> </table> </div> </form> </div> <div class="col-md-6 permission-area"> <form method="post"> {% csrf_token %} <input type="hidden" name="postType" value="permission"> <div class="panel panel-default"> <!-- Default panel contents --> <div class="panel-heading"> <i class="fa fa-sitemap" aria-hidden="true"></i> 权限分配 {% if rid %} <button class="right btn btn-success btn-xs" style="padding: 2px 8px;margin: -3px;"> <i class="fa fa-save" aria-hidden="true"></i> 保存 </button> {% endif %} </div> <div class="panel-body" style="color: #d4d4d4;padding: 10px 5px;"> 提示:点击角色后,才能为其分配权限。 </div> <table class="table"> <tbody> {% for item in all_menu_list %} <tr class="root"> <td><i class="fa fa-caret-down" aria-hidden="true"></i>{{ item.title }}</td> </tr> <tr class="node"> <td> {% for node in item.children %} <div class="parent"> <input id="permission_{{ node.id }}" name="permissions" value="{{ node.id }}" type="checkbox" {% if node.id in role_has_permissions_dict %} checked {% endif %}> <label for="permission_{{ node.id }}">{{ node.title }}</label> </div> <div class="children"> {% for child in node.children %} <div class="child"> <input id="permission_{{ child.id }}" name="permissions" type="checkbox" value="{{ child.id }}" {% if child.id in role_has_permissions_dict %} checked {% endif %} > <label for="permission_{{ child.id }}">{{ child.title }}</label> </div> {% endfor %} </div> {% endfor %} </td> </tr> {% endfor %} </tbody> </table> </div> </form> </div> </div> {% endblock %} {% block js %} <script> $(function () { bindRootPermissionClick(); }); function bindRootPermissionClick() { $('.permission-area').on('click', '.root', function () { var caret = $(this).find('i'); if (caret.hasClass('fa-caret-right')) { caret.removeClass('fa-caret-right').addClass('fa-caret-down'); $(this).next().removeClass('hide'); } else { caret.removeClass('fa-caret-down').addClass('fa-caret-right'); $(this).next().addClass('hide'); } }) } </script> {% endblock %}
templatetages.rbac.py中相关的simple_tag
# 获取当前角色id,然后给url添加一个rid参数 @register.simple_tag def gen_role_url(request, rid): params = request.GET.copy() params['rid'] = rid return params.urlencode()