一 . 菜单展现
二 . 合并删除
咱们能够把全部的删除都合并成一个函数这样就会减小不少的代码.html
思路: 在url里面须要传两个参数,一个是要删的id 一个是名字前端
三 .权限展现
咱们要实现两个功能
1. 咱们点击菜单管理的一级菜单,展现所属他的全部权限.数据库
2. 让权限按照一级菜单的分类进行展现.django
3. 点击权限管理的二级菜单,让所属它的功能进行展开与闭合后端
咱们要想让权限按照一级菜单的分类进行展现的话,须要把二级菜单的功能放到二级菜单的children里面,这样展现起来就不会乱了顺序.api


from django.shortcuts import render, redirect, reverse from rbac import models from rbac.form import RoleForm, MenuForm from django.db.models import Q # Create your views here. def role_list(request): all_role = models.Role.objects.all() return render(request, 'rbac/role_list.html', {'all_role': all_role}) def role_change(request, edit_id=None): obj = models.Role.objects.filter(pk=edit_id).first() if edit_id: form_obj = RoleForm(instance=obj) else: form_obj = RoleForm() if request.method == 'POST': form_obj = RoleForm(request.POST, instance=obj) if form_obj.is_valid(): form_obj.save() return redirect('role_list') return render(request, 'rbac/role_add.html', {'form_obj': form_obj}) # 全部的删除均可以用下面的delete函数 # def role_del(request, del_id): # models.Role.objects.filter(pk=del_id).delete() # return redirect('role_list') def menu_list(request): # 这种获取到的是all(),到前段展现的时候就须要.字段名,若是只直接筛选完的 all_menu = models.Menu.objects.all() mid = request.GET.get('mid') permission_id = models.Permission.objects.filter(menu_id=mid).first().id # print(permission_id) if mid: # Q 是为了让二级菜单和隶属于他的功能所有展现,要否则只会展现一种 all_permission = models.Permission.objects.filter(Q(parent_id=permission_id) | Q(menu_id=mid)).values('id', 'parent_id', 'title', 'url', 'name', 'menu__title') else: all_permission = models.Permission.objects.all().values('id', 'parent_id', 'title', 'url', 'name', 'menu__title') permission_dict = {} for i in all_permission: if not i.get('parent_id'): i['children'] = [] permission_dict[i['id']] = i # print(i) for i in all_permission: pid = i.get('parent_id') if pid: permission_dict[pid]['children'].append(i) # 这种传参没用用modelform的到前段循环展现的时候须要 .字段名字才能够 {{permission.name}} return render(request, 'rbac/menu_list.html', {'mid': mid, 'all_menu': all_menu, 'all_permission': permission_dict.values()}) def menu_change(request, edit_id=None): obj = models.Menu.objects.filter(pk=edit_id).first() form_obj = MenuForm(instance=obj) if edit_id else MenuForm() if request.method == 'POST': form_obj = MenuForm(request.POST, instance=obj) if form_obj.is_valid(): form_obj.save() return redirect('menu_list') # 这种传参用了modelform的 到前段循环展现的时候,直接{{field}} 就能够 return render(request, 'rbac/form.html', {'form_obj': form_obj}) def delete(request, table, del_id): # 用反射的原理,这里的models是models.py文件 table_class = getattr(models, table.capitalize()) # 这里的table_class就至关于models.表名 table_class.objects.filter(pk=del_id).delete() return redirect(f'{table}_list')
前端在循环展现权限的时候, 须要进行两次循环, 第一次是循环出二级菜单, 第二次循环出二级菜单children里面的功能,这样顺序才是咱们想要的app
下面的效果就是js的点击事件功能了,点击添加, 移除类属性ide
注意:
if条件里面的两个数据类型不同,不能直接比较,从数据库中提取的是int类型, 从url中获取的是str类型, 要把他们两个变成同一类型, 第一种方法是在后端把url获取的变成int, 第二种方法就是在前端把int类型加个safe变成字符串