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()) # 新增权限的name_set 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(): permission_obj_list = [models.Permission(**i) for i in add_formset.cleaned_data] query_list = models.Permission.objects.bulk_create(permission_obj_list) add_formset = AddFormSet() for i in query_list: permissions_name_set.add(i.name) # 要删除的权限 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 init_permission(self): url = routes.get_all_url_dict() # self.get_permission_list(self,'org', '组织权限', 'orgemp', '人员') menu_list = self.menu_list select_str = menu_list["select_str"] menu_name = menu_list["menu_name"] table_name = menu_list["table_name"] table_title = menu_list["table_title"] for k, v in url.items(): name = v['name'] url = v['url'] if select_str in str(k): menu_id = self.check_menu(menu_name) if table_name in str(k): self.add_permission(name_class=table_name, name=name, url=url, menu_id=menu_id, title=table_title)
def multi_permissions(request): """批量操作权限""" post_type = request.GET.get('type') generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0) update_formset_class = formset_factory(MultiEditPermissionForm, extra=0) # 创建formset类 generate_formset = None update_formset = None # 用户提交区 if request.method == 'POST' and post_type == 'generate': # 批量添加 formset = generate_formset_class(data=request.POST) if formset.is_valid(): # 表单验证 object_list = [] # 先判断有没有唯一索引限制 post_row_list = formset.cleaned_data has_error = False for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] try: new_object = models.Permission(**row_dict) new_object.validate_unique() # 唯一字段判断 object_list.append(new_object) except Exception as e: formset.errors[i].update(e) generate_formset = formset has_error = True if not has_error: # 没有错误就批量增加 models.Permission.objects.bulk_create( object_list, batch_size=100) # 批量增加语法bulk_create else: # 显示错误信息 generate_formset = formset if request.method == 'POST' and post_type == 'update': # 批量更新 formset = update_formset_class(data=request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): # 循环总个数 row_dict = post_row_list[i] permission_id = row_dict.pop('id') # 拿到修改页面的id try: row_object = models.Permission.objects.filter( id=permission_id).first() # 数据库已有数据 # 反射 for k, v in row_dict.items(): setattr(row_object, k, v) row_object.validate_unique() # 检测唯一 row_object.save() except Exception as e: formset.errors[i].update(e) update_formset = formset else: update_formset = formset # 展示区 # 1. 取项目中所有URL """ all_url_dict格式 { rbac:role_list {'name': 'rbac:role_list', 'url': '/rbac/role/list/'}, rbac:role_add {'name': 'rbac:role_add', 'url': '/rbac/role/add/'}, ... } """ all_url_dict = get_all_url_dict() router_name_set = set(all_url_dict.keys()) # 设为集合 # 2. 取数据库中所有URL permission = models.Permission.objects.all().values( 'id', 'title', 'name', 'url', 'menu_id', 'pid_id') permission_dict = OrderedDict() permission_name_set = set() # 创建集合 for row in permission: permission_dict[row['name']] = row permission_name_set.add(row['name']) # 放到集合里 """ permission_dict格式 { rbac:role_list {'name': 'rbac:role_list','title':'角色列表', 'url': '/rbac/role/list/'....}, ... } """ # 判断代码中path中和数据库中是否相等(防止万一改到代码后出现bug) for name, value in permission_dict.items(): router_row_dict = all_url_dict.get(name) if not router_row_dict: continue if value['url'] != router_row_dict['url']: value['url'] = '路由和数据库中不一致!' # 3. 拿到两个集合可以进行对比(集合语法),参考 【总】权限分配思路.md # 3.1 计算出应该增加的name '''关于formset的使用可以参考 【https://gitee.com/Zok/formset】 代码库''' if not generate_formset: generate_name_list = router_name_set - permission_name_set # 生成新的 # 制作添加的 formset generate_formset = generate_formset_class(initial=[ row_dict for name, row_dict in all_url_dict.items() if name in generate_name_list ]) # 列表生成式,把应该增加的放到initial中 # 3.2 计算该删除的name delete_name_list = permission_name_set - router_name_set # 删除多的 delete_row_list = [ row_dict for name, row_dict in permission_dict.items() if name in delete_name_list ] # 列表生成式 # 3.3 计算出该更新的name if not update_formset: update_name_list = permission_name_set & router_name_set # 更新(&取交集) # 制作formset (必须要一个隐藏的id字段,才能编辑)在数据库permission中取,因为数据齐全有title,menu_id等 update_formset = update_formset_class(initial=[ row_dict for name, row_dict in permission_dict.items() if name in update_name_list ]) # 列表生成式,把应该增加的放到initial中 return render( request, 'rbac/multi_permissions.html', { 'generate_formset': generate_formset, 'delete_row_list': delete_row_list, 'update_formset': update_formset, })
def multi_permission(request): 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']) """ { 'url别名':{'name':url别名,'url':url}, ... } """ # 数据库中权限的所有的别名 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(): 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() 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_permission.html', { 'del_formset': del_formset, 'update_formset': update_formset, 'add_formset': add_formset, })
def multi_permissions(request): """ 批量操作权限 :param request: :return: """ post_type = request.GET.get('type') generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0) update_formset_class = formset_factory(MultiEditPermissionForm, extra=0) generate_formset = None update_formset = None if request.method == 'POST' and post_type == 'generate': # pass # 批量添加 formset = generate_formset_class(data=request.POST) if formset.is_valid(): object_list = [] post_row_list = formset.cleaned_data has_error = False for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] try: new_object = models.Permission(**row_dict) new_object.validate_unique() object_list.append(new_object) except Exception as e: formset.errors[i].update(e) generate_formset = formset has_error = True if not has_error: models.Permission.objects.bulk_create(object_list, batch_size=100) else: generate_formset = formset if request.method == 'POST' and post_type == 'update': # pass # 批量更新 formset = update_formset_class(data=request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] permission_id = row_dict.pop('id') try: row_object = models.Permission.objects.filter(id=permission_id).first() for k, v in row_dict.items(): setattr(row_object, k, v) row_object.validate_unique() row_object.save() except Exception as e: formset.errors[i].update(e) update_formset = formset else: update_formset = formset # 1. 获取项目中所有的URL all_url_dict = get_all_url_dict() """ { 'rbac:role_list':{'name': 'rbac:role_list', 'url': '/rbac/role/list/'}, 'rbac:role_add':{'name': 'rbac:role_add', 'url': '/rbac/role/add/'}, .... } """ router_name_set = set(all_url_dict.keys()) # 2. 获取数据库中所有的URL permissions = models.Permission.objects.all().values('id', 'title', 'name', 'url', 'menu_id', 'pid_id') permission_dict = OrderedDict() permission_name_set = set() for row in permissions: permission_dict[row['name']] = row permission_name_set.add(row['name']) """ { 'rbac:role_list': {'id':1,'title':'角色列表',name:'rbac:role_list',url.....}, 'rbac:role_add': {'id':1,'title':'添加角色',name:'rbac:role_add',url.....}, ... } """ for name, value in permission_dict.items(): router_row_dict = all_url_dict.get(name) # {'name': 'rbac:role_list', 'url': '/rbac/role/list/'}, if not router_row_dict: continue if value['url'] != router_row_dict['url']: value['url'] = '路由和数据库中不一致' # 3. 应该添加、删除、修改的权限有哪些? # 3.1 计算出应该增加的name if not generate_formset: generate_name_list = router_name_set - permission_name_set generate_formset = generate_formset_class( initial=[row_dict for name, row_dict in all_url_dict.items() if name in generate_name_list]) # 3.2 计算出应该删除的name delete_name_list = permission_name_set - router_name_set delete_row_list = [row_dict for name, row_dict in permission_dict.items() if name in delete_name_list] # 3.3 计算出应该更新的name if not update_formset: update_name_list = permission_name_set & router_name_set update_formset = update_formset_class( initial=[row_dict for name, row_dict in permission_dict.items() if name in update_name_list]) return render( request, 'rbac/multi_permissions.html', { 'generate_formset': generate_formset, 'delete_row_list': delete_row_list, 'update_formset': update_formset, } )
def multi_permissions(request): """ 批量操作权限 :param request: :return: """ post_type = request.GET.get('type') generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0) update_formset_class = formset_factory(MultiEditPermissionForm, extra=0) generate_formset = None update_formset = None if request.method == 'POST' and post_type == 'generate': # "批量增加" formset = generate_formset_class(data=request.POST) if formset.is_valid(): object_list = [] post_row_list = formset.cleaned_data has_error = False for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] # 拿到每一行的数据 try: new_object = models.Permission(**row_dict) # 实例化一个对象 new_object.validate_unique() object_list.append(new_object) # 用于批量增加 except Exception as e: formset.errors[i].update(e) generate_formset = formset # 页面上去展示错误信息 has_error = True if not has_error: models.Permission.objects.bulk_create( object_list, batch_size=100) # 批量增加100条 else: generate_formset = formset if request.method == 'POST' and post_type == 'update': # "批量更新" formset = update_formset_class(data=request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] permission_id = row_dict.pop('id') try: row_object = models.Permission.objects.filter( id=permission_id).first() for k, v in row_dict.items(): setattr(row_object, k, v) row_object.validate_unique() row_object.save() except Exception as e: formset.errors[i].update(e) update_formset = formset else: update_formset = formset # 1.获取 自动发现 项目中所有的URL all_url_dict = get_all_url_dict() """ all_url_dct = { ' rbac:user_list':{'name': 'rbac:user_list', 'url': '/rbac/user/list/'}, ' rbac:user_add':{'name': 'rbac:user_add', 'url': '/rbac/user/add/'}, ' rbac:user_edit':{'name': 'rbac:user_edit', 'url': '/rbac/user/edit/(?P<pk>\\d+)/'}, ' rbac:user_del':{'name': 'rbac:user_del', 'url': '/rbac/user/del/(?P<pk>\\d+)/'}, }""" router_name_set = set( all_url_dict.keys()) # 获取项目中所有URL的name 'rbac:user_del' # 2.获取数据库中所有的URL permissions = models.Permission.objects.all().values( 'id', 'title', 'name', 'url', 'menu_id', 'pid_id') # QuerySet类型 permission_dict = OrderedDict() permission_name_set = set() # 数据库中的name集合。 for row in permissions: permission_dict[row['name']] = row permission_name_set.add(row['name']) """ permission_dict{ 'rbac:role_list': {'id':1,'title':'角色列表',name:'rbac:role_list',url.....}, 'rbac:role_add': {'id':1,'title':'添加角色',name:'rbac:role_add',url.....}, ... } """ for name, value in permission_dict.items(): router_row_dict = all_url_dict.get(name) if not router_row_dict: continue if value['url'] != router_row_dict['url']: value['url'] = '路由和数据库中不一致,请检查!' # value['url'] = value['url'] +"$$$"+ router_row_dict['url'] # 3.应该添加,删除,修改的权限有哪些 # 3.1 自动发现的权限 "大于" 数据库中的权限 --> 实现批量添加url 的name if not generate_formset: generate_name_list = router_name_set - permission_name_set generate_formset = generate_formset_class(initial=[ row_dict for name, row_dict in all_url_dict.items() if name in generate_name_list ]) # 自动发现有,数据库没有,就放到页面去展示,并批量添加 # 3.2 数据库中的权限 "大于" 自动发现的权限 --> 批量删除 delete_name_list = permission_name_set - router_name_set delete_row_list = [ row_dict for name, row_dict in permission_dict.items() if name in delete_name_list ] # 3.3 自动发现的权限 和数据库中的权限 个数一致,值有不一致的 # {'payment_list', 'payment_del', 'customer_tpl', 'customer_del', 'customer_import', 'payment_add', 'customer_edit', 'payment_edit', 'customer_list', 'customer_add'} if not update_formset: update_name_list = permission_name_set & router_name_set update_formset = update_formset_class(initial=[ row_dict for name, row_dict in permission_dict.items() if name in update_name_list ]) return render( request, 'rbac/multi_permission.html', { 'generate_formset': generate_formset, 'delete_row_list': delete_row_list, 'update_formset': update_formset, })
def multi_permissions(request): """ 批量操作权限 :param request: :return: """ post_type = request.GET.get('type') MultiPermissionFormSet = formset_factory(MultiPermissionForm, extra=0) generate_formset = None update_formset = None if request.method == 'POST' and post_type == 'generate': formset = MultiPermissionFormSet(request.POST) if not formset.is_valid(): generate_formset = formset else: for row_dict in formset.cleaned_data: row_dict.pop('id') models.Permission.objects.create(**row_dict) if request.method == 'POST' and post_type == 'update': formset = MultiPermissionFormSet(request.POST) if formset.is_valid(): for row_dict in formset.cleaned_data: permission_id = row_dict.pop('id') models.Permission.objects.filter(id=permission_id).update( **row_dict) else: update_formset = formset # 1.1 去数据库中获取所有权限 # [{},{}] permissions = models.Permission.objects.all().values( 'id', 'title', 'url', 'name', 'menu_id', 'pid_id') # {'rbac:menu_list':{},'rbac:menu_add':{..}} permisssion_dict = OrderedDict() for per in permissions: permisssion_dict[per['name']] = per # 1.2 数据库中有的所有权限name的集合 permission_name_set = set(permisssion_dict.keys()) # 2.1 获取路由系统中所有的URL # {'rbac:menu_list':{'url':.... },,,} router_dict = get_all_url_dict(ignore_namespace_list=['admin']) for row in permissions: name = row['name'] if name in router_dict: router_dict[name].update(row) # 2.2 路由系统中的所有权限name的集合 router_name_set = set(router_dict.keys()) # 需要新建:数据库无、路由有 if not generate_formset: generate_name_list = router_name_set - permission_name_set generate_formset = MultiPermissionFormSet(initial=[ row for name, row in router_dict.items() if name in generate_name_list ]) # 需要删除:数据库有、路由无 destroy_name_list = permission_name_set - router_name_set destroy_formset = MultiPermissionFormSet(initial=[ row for name, row in permisssion_dict.items() if name in destroy_name_list ]) # 需要更新:数据库有、路由有 if not update_formset: update_name_list = permission_name_set.intersection(router_name_set) update_formset = MultiPermissionFormSet(initial=[ row for name, row in router_dict.items() if name in update_name_list ]) return render( request, 'rbac/multi_permissions.html', { 'destroy_formset': destroy_formset, 'update_formset': update_formset, 'generate_formset': generate_formset, })
def multi_permissions_list(request): """获取当前项目中的所有URL,别名,反向解析自动拼接namespace""" """ project_url_dict = { "rbac:menu_list" : {name:menu_list, url:/rbac/menu/list/} } """ # 实例化一个form_class的类,参数1为自定义的form表单, extra传入需要批量生成的表单数量,生成一个formset类 formset_add_class = formset_factory(MultiAddForm, extra=0) formset_update_class = formset_factory(MultiUpdateForm, extra=0) post_type = request.GET.get("type") # 看一下提交来的POST请求是什么类型 add_forms = None # 设置一个add_forms的标志位 update_forms = None # 设置一个update_forms的标志位 if request.method == "POST" and post_type == "add": # 如果是个POST请求并且type类型为add,就是个批量增加操作 formset = formset_add_class(data=request.POST) # 把POST请求带过来的数据交给forms组件来进行校验 if formset.is_valid(): # 查看校验是否成功 has_error = False # 这个标志位用于查看下面遍历的所有数据是否全都合法,全都合法再批量入数据库 obj_list = [] # 处于SQL性能考虑,在这里创建一个合法row的列表,用于下面的for循环结束后统一添加 post_data = formset.cleaned_data # 先缓存一下cleaned_data,以便判断是否存在unique唯一索引报错 for index in range(0, formset.total_form_count()): # 利用post_data和cleaned_data数据索引一致的特点,对整体数据进行遍历 row_dict = post_data[index] # 获取当前索引位置的数据 try: new_obj = Permission(**row_dict) # 先尝试用row_dict new_obj.validate_unique() # 判断是否是联合唯一索引 obj_list.append(new_obj) except Exception as e: formset.errors[index].update(e) add_forms = formset # 把add_forms替换为带有错误信息的formset has_error = True if not has_error: # 遍历结束后,一次性批量增加所有合法row, batch_size参数用于设置每次批量增加的数量 Permission.objects.bulk_create(obj_list, batch_size=10) else: # 如果验证失败,错误信息和刚提交的数据都存在这个if条件的formset中,所以要把原来页面的add_forms替换成校验后的formset add_forms = formset if request.method == "POST" and post_type == "update": # 如果是个POST请求并且type类型为add,就是个批量跟新操作 formset = formset_update_class(data=request.POST) # 把POST请求带过来的数据交给forms组件来进行校验 if formset.is_valid(): # 查看校验是否成功 has_error = False # 这个标志位用于查看下面遍历的所有数据是否全都合法,全都合法再批量入数据库 post_data = formset.cleaned_data # 先缓存一下cleaned_data,以便判断是否存在unique唯一索引报错 for index in range(0, formset.total_form_count()): # 利用post_data和cleaned_data数据索引一致的特点,对整体数据进行遍历 row_dict = post_data[index] # 获取当前索引位置的数据 permissions_id = row_dict.pop("id") # 获取当前row的ID,顺便删除ID字段,因为修改内容不需要改ID try: row_obj = Permission.objects.get(id=permissions_id) # 通过ID获取数据库中原有的这个row对象 for k, v in row_dict.items(): # 遍历row_dict中的每个键值对 setattr(row_obj, k, v) # 通过setattr反射,来把每个键值对设置成row_obj的属性和值 row_obj.validate_unique() # 检测字段唯一性 row_obj.save() # 保存row except Exception as e: formset.errors[index].update(e) update_forms = formset else: # 验证不成功的情况 update_forms = formset # 替换formset以便显示错误信息 project_url_dict = routes.get_all_url_dict() # 获取项目中的所有URL route_name_set = set(project_url_dict.keys()) # 并建立一个集合 # 获取数据库中的所有URL database_url_queryset = Permission.objects.all().values("id", "title", "name", "url", "menu_id", "pid_id") database_url_dict = OrderedDict() permission_name_set = set() # 建立一个数据库中的所有URL的集合 for row in database_url_queryset: # 遍历数据库索取来的URL的queryset集合 database_url_dict[row["name"]] = row # 往字典内存放数据 {name:{URL的各个字段+记录}} permission_name_set.add(row["name"]) # 往集合内插入URL的别名 # 遍历一下项目和数据库两个URL集合,看一下有没有name是一样的,但是url不一致的情况,如果有这种情况,给挑出来 for name, row_dict in database_url_dict.items(): # 遍历数据库中的所有url别名和url_dict route_dict = project_url_dict.get(name) # 获取项目中别名相同的url_dict if not route_dict: # 如果项目中不存在这个url_dict, 那就属于需要更新的内容,直接跳过 continue else: # 进入这里就表示项目和数据库中都有这个url_dict if row_dict["url"] != route_dict["url"]: # 如果这两个url内容一致,就拉倒不管他,如果不一致 row_dict["url"] = "项目路由和数据库中不一致,请检查" # 直接写上提示语,就没必要展示URL了 if not add_forms: # 查看add_forms标志位是否被赋值 add_name_list = route_name_set - permission_name_set # 如果项目里面有,数据库里面没有,就需要进行添加 add_forms = formset_add_class( # 通过initial参数来控制生成的form数量 # 遍历数据库中所有的URL,通过别名判断查找出需要增加的URL字典 initial=[row_dict for name, row_dict in project_url_dict.items() if name in add_name_list]) del_name_list = permission_name_set - route_name_set # 如果项目里面没有,数据库里面有,就需要进行删除 # 遍历数据库中所有的URL,通过别名判断查找出需要删除的URL字典 del_rows = [row_dict for name, row_dict in database_url_dict.items() if name in del_name_list] if not update_forms: # 查看update_forms标志位是否被赋值 update_name_list = permission_name_set & route_name_set # 取数据库和项目两个集合的并集,以备修改 # 遍历数据库中所有的URL,通过别名判断查找出需要修改的URL字典 update_forms = formset_update_class( initial=[row_dict for name, row_dict in database_url_dict.items() if name in update_name_list]) return render(request, "rbac/multi_permissions.html", { "add_forms": add_forms, "del_rows": del_rows, "update_forms": update_forms})
def multi_permission(request): ''' 批量增改权限 :param request: :return: ''' post_type = request.GET.get('type') formset_add_class = formset_factory(menu.MultiAddPermissionsForm, extra=0) generate_formset = None # 批量新增权限 if request.method == 'POST' and post_type == 'generate': formset = formset_add_class(request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data obj_list = [] has_error = False for i in range(0, formset.total_form_count()): row = post_row_list[i] try: obj = models.Permission(**row) obj.validate_unique() obj_list.append(obj) except Exception as e: formset.errors[i].update(e) generate_formset = formset has_error = True if not has_error: models.Permission.objects.bulk_create( obj_list, batch_size=50) # batch_size=50设置一次批量增加条数 else: generate_formset = formset # 批量更新权限 update_formset_class = formset_factory(menu.MultiUpdatePermissionsForm, extra=0) update_formset = None if request.method == 'POST' and post_type == 'update': formset = update_formset_class(request.POST) if formset.is_valid(): post_update_list = formset.cleaned_data for i in range(0, formset.total_form_count()): update_row = post_update_list[i] permission_id = update_row.pop('pid') try: update_obj = models.Permission.objects.filter( pid=permission_id).first() for k, v in update_row.items(): setattr(update_obj, k, v) update_obj.validate_unique() update_obj.save() except Exception as e: formset.errors[i].update(e) update_formset = formset else: update_formset = formset # 自动发现项目中所有的url auto_get_all_url = routes.get_all_url_dict() router_name_set = set(auto_get_all_url.keys()) # 获取数据库中所有的url permission_list = models.Permission.objects.all().values( 'pid', 'title', 'name', 'url', 'menu_id', 'p_id_id') permission_dict = OrderedDict() for row in permission_list: permission_dict[row['name']] = row permission_name_set = set(permission_dict.keys()) for name, value in permission_dict.items(): router_row_dict = auto_get_all_url.get(name) if not router_row_dict: continue if value['url'] != router_row_dict['url']: value['url'] = '路由和数据库不一致' # 获取待操作权限名称列表 # 待添加权限 if not generate_formset: generate_name_list = router_name_set - permission_name_set generate_formset = formset_add_class(initial=[ row_dict for name, row_dict in auto_get_all_url.items() if name in generate_name_list ]) # 待删除权限 delete_name_list = permission_name_set - router_name_set delete_row_list = [ row_dict for name, row_dict in permission_dict.items() if name in delete_name_list ] # print(delete_row_list) # 待更新权限 if not update_formset: update_name_list = router_name_set & permission_name_set update_formset = update_formset_class(initial=[ row_dict for name, row_dict in permission_dict.items() if name in update_name_list ]) return render( request, 'rbac/multi_permission.html', { 'generate_formset': generate_formset, 'delete_row_list': delete_row_list, 'update_formset': update_formset })
def multi_permissions(request): ''' 批量操作权限 :param request: :return: ''' post_type = request.GET.get("type") generate_formset = None update_formset = None update_formset_class = formset_factory(MultiEditPermissionForm, extra=0) generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0) if request.method == "POST" and post_type == "generate": # 批量添加 formset = generate_formset_class(data=request.POST) if formset.is_valid(): has_error = False object_list = [] post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] if not row_dict: continue try: new_object = models.Permission(**row_dict) new_object.validate_unique() object_list.append(new_object) except Exception as e: formset.errors[i].update(e) generate_formset = formset has_error = True if not has_error: models.Permission.objects.bulk_create(object_list, batch_size=100) # 批量添加 else: generate_formset = formset if request.method == "POST" and post_type == "update": # 批量更新 formset = update_formset_class(data=request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] permission_id = row_dict.pop("id") try: row_object = models.Permission.objects.filter( pk=permission_id).first() for k, v in row_dict.items(): setattr(row_object, k, v) row_object.validate_unique() row_object.save() except Exception as e: formset.errors[i].update(e) update_formset = formset else: update_formset = formset # 1.获取项目中,所有的URL all_url_dict = get_all_url_dict() router_name_set = set(all_url_dict.keys()) # 2. 获取数据库中所有的url permissions = models.Permission.objects.all().values( "id", "title", "name", "url", "menu_id", "pid_id") permission_dict = OrderedDict() permission_name_set = set() for row in permissions: permission_dict[row.get("name")] = row permission_name_set.add(row.get("name")) # permission_name_set = set(permission_dict.keys()) # 这个循环主要是为了,进行更新操作的时候。有可能自动发现和数据库中 name 一样而url不一样时。强制更改一下 # 让用户去自己去检查一下。 到底要使用 那个url。 需要用户自己手动填写 for name, value in permission_dict.items(): router_row = all_url_dict.get(name) if not router_row: continue if value.get("url") != router_row.get("url"): value["url"] = "路由和数据库中不一致,请检查。并填写正确的 url!!" # 3. 应该要 添加,删除,修改的权限有哪些 # 3.1 计算出应该添加的name 并生成 formset (自动发现有的,数据库没有的。所以要循环的是 自动发现查询出的字典) if not generate_formset: generate_name_list = router_name_set - permission_name_set # 增加列表 generate_formset = generate_formset_class(initial=[ row_dict for name, row_dict in all_url_dict.items() if name in generate_name_list ]) # 3.2 计算出,应该删除的name,(数据库有的,自动发现 没有的。所以要循环的是 数据库查询出的字典) delete_name_list = permission_name_set - router_name_set # 删除列表 # 页面展示时 不需要删除的formset 只提供一个删除按钮就好 delete_row_list = [ row_dict for name, row_dict in permission_dict.items() if name in delete_name_list ] # 3.3 计算出应该更新的name (数据库有的,自动发现有的。所以要循环的是 数据库查询出的字典) if not update_formset: update_name_list = permission_name_set & router_name_set # 更新列表 update_formset = update_formset_class(initial=[ row_dict for name, row_dict in permission_dict.items() if name in update_name_list ]) return render( request, "rbac/multi_permission.html", { "generate_formset": generate_formset, "delete_row_list": delete_row_list, "update_formset": update_formset }, )
def multi_permission(request): post_type = request.GET.get('type') formset_add_class = formset_factory(MultiAddPermissionsForm, extra=0) update_formset_class = formset_factory(MultiUpdatePermissionsForm, extra=0) generate_formset = None update_formset = None # 添加url if request.method == 'POST' and post_type == 'generate': formset = formset_add_class(request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data obj_list = [] has_error = False for i in range(0, formset.total_form_count()): row = post_row_list[i] try: obj = models.Permission(**row) obj.validate_unique() # 判断唯一性 obj_list.append(obj) except Exception as e: formset.errors[i].update(e) generate_formset = formset has_error = True if not has_error: models.Permission.objects.bulk_create(obj_list, batch_size=50) else: generate_formset = formset # 更新url if request.method == 'POST' and post_type == 'update': formset = update_formset_class(request.POST) if formset.is_valid(): post_update_list = formset.cleaned_data for i in range(0, formset.total_form_count()): update_row = post_update_list[i] print(update_row) permission_id = update_row.pop('id') try: update_obj = models.Permission.objects.filter( id=permission_id).first() for k, v in update_row.items(): setattr(update_obj, k, v) update_obj.validate_unique() update_obj.save() except Exception as e: formset.errors[i].update(e) update_formset = formset else: update_formset = formset # 获得程序和数据库中的url auto_get_all_url = routes.get_all_url_dict() routes_name_set = set(auto_get_all_url.keys()) permission_list = models.Permission.objects.all().values( 'id', 'title', 'url', 'name', 'menu_id', 'pid_id') permission_dict = OrderedDict() for item in permission_list: permission_dict[item['name']] = item permission_set = set(permission_dict.keys()) for name, value in permission_dict.items(): router_row_dict = auto_get_all_url.get(name) if not router_row_dict: continue if value['url'] != router_row_dict['url']: value['url'] = '路由和数据库中不一致!' # 待增加的url if not generate_formset: generate_name_list = routes_name_set - permission_set generate_formset = formset_add_class(initial=[ row_dict for name, row_dict in auto_get_all_url.items() if name in generate_name_list ]) # 待删除url delete_name_list = permission_set - routes_name_set delete_row_list = [ row_dict for name, row_dict in permission_dict.items() if name in delete_name_list ] # 待更新url if not update_formset: update_name_list = permission_set & routes_name_set update_formset = update_formset_class(initial=[ row_dict for name, row_dict in permission_dict.items() if name in update_name_list ]) return render( request, 'rbac/multi_permission.html', { 'generate_formset': generate_formset, 'delete_row_list': delete_row_list, 'update_formset': update_formset })
def multi_permissions(request): """ 批量操作权限(添加、修改) :param request: :return: """ # 获取用户操作的类型(批量添加 or 批量修改) post_type = request.GET.get('type') generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0) update_formset_class = formset_factory(MultiEditPermissionForm, extra=0) # 错误信息标志位 has_generate_error = False has_update_error = False # 增:批量添加权限 if request.method == 'POST' and post_type == 'generate': formset = generate_formset_class(data=request.POST) if formset.is_valid(): object_list = [] # formset中没有错误信息,则将用户提交的数据获取到 post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] try: new_object = models.Permission(**row_dict) # 唯一校验:检查当前对象在数据库是否存在 new_object.validate_unique() object_list.append(new_object) except Exception as e: formset.errors[i].update(e) generate_formset_error = formset has_generate_error = True if not has_generate_error: # 获取所有数据后,再统一添加到数据库 models.Permission.objects.bulk_create(object_list, batch_size=100) else: generate_formset_error = formset has_generate_error = True # 改:批量修改权限 if request.method == 'POST' and post_type == 'update': formset = update_formset_class(data=request.POST) if formset.is_valid(): post_row_list = formset.cleaned_data for i in range(0, formset.total_form_count()): row_dict = post_row_list[i] # 指定当前修改的权限id permission_id = row_dict.pop('id') try: row_object = models.Permission.objects.filter( id=permission_id).first() # 通过反射批量更新row_object对象的属性值 for k, v in row_dict.items(): setattr(row_object, k, v) # 唯一校验通过,直接保存到数据库 row_object.validate_unique() row_object.save() except Exception as e: formset.errors[i].update(e) update_formset_error = formset has_update_error = True else: update_formset_error = formset has_update_error = True reload_session(request) # 查: # 1. 获取项目中所有的URL all_url_dict = get_all_url_dict() router_name_set = set(all_url_dict.keys()) # 2 获取数据库中所有的URL permissions = models.Permission.objects.all().values( 'id', 'title', 'name', 'url', 'menu_id', 'pid_id') permission_dict = OrderedDict() permission_name_set = set() for row in permissions: permission_dict[row['name']] = row permission_name_set.add(row['name']) # 3 项目url和数据库url比较 for name, value in permission_dict.items(): router_row_dict = all_url_dict.get(name) if not router_row_dict: continue if value['url'] != router_row_dict['url']: value['url'] = '路由和数据库中不一致' # 3.1 计算出应该增加的name generate_name_list = router_name_set - permission_name_set generate_formset = generate_formset_class(initial=[ row_dict for name, row_dict in all_url_dict.items() if name in generate_name_list ]) # 3.2 计算出应该删除的name delete_name_list = permission_name_set - router_name_set delete_row_list = [ row_dict for name, row_dict in permission_dict.items() if name in delete_name_list ] # 3.3 计算出应该更新的name update_name_list = permission_name_set & router_name_set update_formset = update_formset_class(initial=[ row_dict for name, row_dict in permission_dict.items() if name in update_name_list ]) # 判断是否有错误信息 generate_formset = generate_formset_error if has_generate_error else generate_formset update_formset = update_formset_error if has_update_error else update_formset return render( request, 'rbac/multi_permissions.html', { 'generate_formset': generate_formset, 'delete_row_list': delete_row_list, 'update_formset': update_formset, })
def multi_permissions(request): """ 批量操作权限 :param request: :return: """ post_type = request.GET.get('type') # 编辑和删除使用的modelformset FormSet = modelformset_factory(models.Permission, MultiPermissionForm, extra=0) # 新增使用formset AddFormSet = formset_factory(MultiPermissionForm, extra=0) # 从数据库中获取到所有的URL 权限 permissions = models.Permission.objects.all() # 从路由系统中获取到所有的URL { name: { name url } } router_dict = get_all_url_dict(ignore_namespace_list=[ 'admin', ]) # 数据库中权限的url别名的集合 permissions_name_set = set([i.name for i in permissions]) # 路由系统中权限的url别名的集合 router_name_set = set(router_dict.keys()) # 新增权限的别名的集合 add_name_set = router_name_set - permissions_name_set # add_formset = AddFormSet(initial=[ {'url':'sssss','title':'1111'},{'url':'2222','title':'333'}]) 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(): permission_obj_list = [ models.Permission(**i) for i in add_formset.cleaned_data ] query_list = models.Permission.objects.bulk_create( permission_obj_list) add_formset = AddFormSet() for i in query_list: permissions_name_set.add(i.name) # 待删除权限的别名的集合 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)) # print(add_formset.errors) return render( request, 'rbac/multi_permissions.html', { 'del_formset': del_formset, 'update_formset': update_formset, 'add_formset': add_formset, })