进行展示的时候, 肯定是通过formset 来完成这项工作。
1. 获取项目中所有的,想要的权限。 比如保存在一个集合中。 set1
2. 获取数据库中,已经录入了的所有权限。 保存在另一个集合中。 set2

下面 就出现了三种情况:(这里还是需要通过name字段,来进行 判断。 两个集合)
  情况一: set1 比 set2  多。  说明就要把 多出来的 添加到数据库。 批量添加
  情况二: set1 比 set2 少。说明中途可能弃用了一部分url。 数据库就要删除这部分。  批量删除。
  情况三: set1 和 set2 一样多。 但是可能url 改变了。 所以就需要将 set1 中查出的 与 set2 中中查出的, name一样。 url 不一样的,进行批量更新。

OK  大概也就这三种情况:  一个一个的实现:
1.  我已经从项目中获取了,所有的url。 还需要把数据库中,保存着的 permission 的所有信息全部拿到。

    permissions = models.Permission.objects.all().values("pk", "title", "name", "url", "menu_id", "pid_id")permission_dict = OrderedDict()permission_name_set = set()for row in permissions:permission_dict[row.get("name")] = rowpermission_name_set.add(row.get("name"))

在这里也是使用的  OerderdDict  有序字典。
然后放入到了一个  集合当中。 这个集合只放了   每一条记录中的  name 字段的。 信息。
看看什么样:

permission_name_set:{'role_edit', 'customer_edit', 'payment_add', 'payment_list', 'payment_del', 'second_menu_del', 'role_list', 'menu_list', 'menu_del', 'customer_del', 'user_list', 'customer_import', 'user_add', 'user_del', 'permission_edit', 'permission_add', 'customer_tpl', 'reset_pwd', 'second_menu_add', 'menu_add', 'customer_list', 'menu_edit', 'user_edit', 'payment_edit', 'second_menu_edit', 'permission_del', 'customer_add', 'role_add', 'role_del'}

自动获取, 得到的也是一个字典。  也需要将每一个 字典的key 保存到一个集合当中:

all_url_dict = get_all_url_dict()
router_name_set = set(all_url_dict.keys())

router_name_set:{'role_edit', 'customer_edit', 'payment_add', 'multi_permissions', 'payment_list', 'payment_del', 'second_menu_del', 'role_list','menu_list', 'menu_del', 'customer_del', 'user_list', 'customer_import', 'user_add', 'user_del', 'permission_edit', 'permission_add', 'customer_tpl', 'reset_pwd', 'second_menu_add', 'menu_add', 'customer_list', 'menu_edit', 'user_edit', 'payment_edit', 'second_menu_edit', 'permission_del', 'customer_add', 'role_add', 'role_del'}

两个集合有了: 该做差集 并集 操作了!
情况一。 批量添加操作: 自动获取中有的, 数据库没有的, 需要进行添加到数据库:

    # 3.1 计算出应该添加的name 并生成 formset (自动发现有的,数据库没有的。所以要循环的是 自动发现查询出的字典)generate_name_list = router_name_set - permission_name_set  # 增加列表generate_formset_class = formset_factory(MultiAddPermissionForm, extra=0)generate_formset = generate_formset_class(initial=[row_dict for name, row_dict in all_url_dict.items() if name in generate_name_list])

这里有关 formset的操作,不再说: 前面的博客中有提到,(忘了就去复习)
这段代码做的事情就是  将每一个 row_dict 中我保存的  name 和 url 交给了  MultiAddPermissionForm 类里面定义的 name 和 url。
title  肯定是空的。 因为这需要, 用户自己起名字吗嘛!

情况二: 批量删除操作:自动获取中没有的, 数据库有的, 需要从数据库删除掉:

(数据库有的,自动发现 没有的。所以要循环的是 数据库查询出的字典) 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]

删除操作, 就不涉及任何修改了。 直接使用一个列表, 前端循环列表然后,进行渲染就行了!

情况三: 批量更新操作: 自动获取中有的, 数据库有的。

    for name, value in permission_dict.items():router_row = all_url_dict.get(name)  # 从all_url_dict取出key为 name 的值if not router_row:  # 如果没有找到,直接跳过。continueif value.get("url") != router_row.get("url"):  # 找到的情况下, 比对 两个的 url 是否一直value["url"] = "路由和数据库中不一致,请检查。并填写正确的  url!!"# 3.3 计算出应该更新的name (数据库有的,自动发现有的。所以要循环的是 数据库查询出的字典)update_name_list = permission_name_set & router_name_set  # 更新列表update_formset_class = formset_factory(MultiEditPermissionForm, extra=0)update_formset = update_formset_class(initial=[row_dict for name, row_dict in permission_dict.items() if name in update_name_list])

这里先一步对两个 字典中的数据进行了比较。 因为有可能会有  name 是一样的,但是 url 不一样的情况。
那就需要  对 用户有个提示。 所以做了个循环的判断。 发现url 不相等的情况时, 就将这个url 给修改成一个 提示字符串。然后让用户自己去检查,要使用
那个url  然后填写正确的 url  进行保存。

最后就是, 前端页面的渲染,然后让用户进行操作完成之后的保存了!

不论是 添加还是 更新, 都需要一个 form 标签。来进行数据的传递。 action="" 表示。默认使用当前页面的 url 进行数据发送。
为了分清,我这次提交的数据, 是添加的, 还是更新的。 我改变了一下action。

<form method="post" action="?type=generate">......
</form><form method="post" action="?type=update">......
</form>

post_type = request.GET.get("type") 判断GET 中取到的是generate 或者 update 来判断这次的数据,是用于添加或者更新
def multi_permissions(request):'''批量操作权限:param request::return:'''post_type = request.GET.get("type")generate_formset = Noneupdate_formset = Noneupdate_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 = []  # 添加时 将每一个model对象 添加到  object_list  列表中post_row_list = formset.cleaned_datafor i in range(0, formset.total_form_count()):row_dict = post_row_list[i]  # 根据索引拿到 每一行用户上传的数据(得到的是一个字典)if not row_dict:continuetry:new_object = models.Permission(**row_dict)  # 将字典交给Permission模型。得到model对象new_object.validate_unique()  # 判断与数据库中  有限制unique的字段,是否重复。  如果有抛出异常object_list.append(new_object)  # 无异常的 添加到列表中except Exception as e:formset.errors[i].update(e)  #  捕获错误, 并将错误信息,添加到当前form对象的error字典中。generate_formset = formset  # 将接收用户数据之后的 formset 重新赋值给generate_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_datafor 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)  # model对象也是一个 类 实例化来的。 所以使用反射 进行赋值操作row_object.validate_unique()row_object.save()  # 更新只能是,一条一条的 逐条更新。 无法批量except Exception as e:formset.errors[i].update(e)update_formset = formsetelse:update_formset = formset# 1.获取项目中,所有的URLall_url_dict = get_all_url_dict()router_name_set = set(all_url_dict.keys())# 2. 获取数据库中所有的urlpermissions = 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")] = rowpermission_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:continueif 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_permissions_del(request, pk):'''删除操作, 需要给与用户提示。:param reuqest::param pk:  要删除的权限id:return:'''origin_url = memory_reverse(request, "rbac:multi_permissions")permission_queryset = models.Permission.objects.filter(pk=pk)if not permission_queryset:return HttpResponse("菜单不存在")if request.method == "POST":permission_queryset.delete()return redirect(origin_url)return render(request, "rbac/delete.html", {"cancel": origin_url})

批量就做好了, 至于想让,那个权限属于谁。 看实际情况进行。 自行选择。
无法进行,程序的强制限制。 太麻烦

转载于:https://www.cnblogs.com/chengege/p/10723314.html

批量操作权限的页面展示相关推荐

  1. Django博客系统(详情页面展示)

    1. 页面展示 1.在home.views.py文件中定义视图 from django.views import Viewclass DetailView(View):def get(self,req ...

  2. Django博客系统(写博客页面展示)

    1. 页面展示 1.在users.views.py文件中定义视图 from django.views import Viewclass WriteBlogView(LoginRequiredMixin ...

  3. 根据后台的数据设置前端页面展示效果

    2019独角兽企业重金招聘Python工程师标准>>> eg1:后台数据:0:女,1:男: 前端展示效果为:男或女,而不是显示0或1 eg2:后台数据:1:模组1,    2:模组2 ...

  4. python做的数据图表怎么在flask中显示_Flask使用Pyecharts在单个页面展示多个图表的方法...

    在Flask页面展示echarts,主要有两种方法: 方法1.原生echarts方法 自己在前端引入echarts.js文件.自己创建div.自己初始化echarts对象.自己从官网复制并且配置图表. ...

  5. app——分享wap站,数据处理页面展示

    无意中接到了一个小的工作任务:配合手机app端的分享功能做一个wap站,简言之:将手机app端分享的文章id传过来,利用此id再进行一系列的操作,由于文章分为纯文本,图文以及图集的三种类型的文章,因此 ...

  6. 不得不爱开源 Wijmo jQuery 插件集(4)-【手风琴效果】(附页面展示和源码)

    园子中的朋友大家好.在上一篇文章中我们,给大家介绍了 Wijmo Menu 的特性及使用方法.感谢园子中朋友的支持,朋友们的支持给我们写这一系列文章提供了很大的动力.在这篇文章中我们将介绍 Accor ...

  7. html将页面分成三块_导航渲染流程你真的知道从输入URL到页面展示发生了什么吗?(内附思维导图)...

    导航渲染流程 通过这篇文章当你被问到从URL输入到页面展示都发生了什么的时候,基本都能对答如流,甚至可以一直深入的说,说到面试官闭麦哈哈哈~ 以下是本文的思维导图,直接拿图「点个赞」再走吧 ~ 求求了 ...

  8. 在浏览器里,从输入 URL 到页面展示,这中间发生了什么?-学习笔记

    参考来源:极客时间-李兵专栏 从图中可以看出,整个过程需要各个进程之间的配合,浏览器进程.渲染进程和网络进程的职责如下: 浏览器进程主要负责用户交互.子进程管理和文件储存等功能. 网络进程是面向渲染进 ...

  9. asp.net core根据用户权限控制页面元素的显示

    asp.net core根据用户权限控制页面元素的显示 Intro 在 web 应用中我们经常需要根据用户的不同允许用户访问不同的资源,显示不同的内容,之前做了一个 AccessControlHelp ...

最新文章

  1. .NET编码解码(HtmlEncode与HtmlEncode)
  2. Material Designer的低版本兼容实现(十)—— CheckBox RadioButton
  3. 匹配月份_5月份轿车销量榜单出炉 雅阁热销18634辆
  4. UDP千兆以太网FPGA_verilog实现(一、知识搜集)
  5. JSON Web Token(缩写 JWT) 目前最流行、最常见的跨域认证解决方案,前端后端都需要会使用的东西
  6. c++ explicit 修饰构造函数
  7. python3.7.4安装教程win7_Window10下python3.7 安装与卸载教程图解
  8. Flutter TextField 限制只允许输入数字,字母,小数,设置限制小数位数
  9. 手机如何利用IP地址定位城市
  10. 小写字母转大写代码HTML,CSS控制转换字母的大写和小写
  11. 小程序image组件自适应宽高比
  12. 帝国cms用ajax,帝国CMS7.5二次开发之制作Ajax版登录插件(不改系统文件)
  13. 2021-03-27
  14. jeecms oracle v5_jeecms二次开发总结
  15. 大一计算机科学化学,核心导读: 王 龙(北京大学计算机科学技术系学生,江西省高考理科状元): 化学被称为理科中的文科。题目量较多,单题分较...
  16. java 表格tr td_table、tr、td表格的行、单元格等属性说明
  17. 《从零开始的 RPG 游戏制作教程》第十四期:自制技能
  18. 【已注册】充QQ业务软件
  19. 常用工具:自媒体视频素材网站,自媒体视频剪辑,自媒体排版工具
  20. 传说之下打开debug模式超超超超超超超超详细方法

热门文章

  1. android源码已关联设备,获取android设备已安装应用信息
  2. 卫星轨道的估计问题(Matlab)(一):理论基础
  3. java netty 面试_Java 200+ 面试题补充② Netty 模块
  4. L2-012 关于堆的判断(模拟堆+字符串处理)
  5. 笔记︱范数正则化L0、L1、L2-岭回归Lasso回归(稀疏与特征工程)
  6. OpenCV之滑动条的创建和使用
  7. Apple Watch新玩法:手势操控无人机
  8. 自己动手,在macOS High Sierra中编译一个可debug的JDK
  9. 树形控件显示数据库数据项
  10. 单例模式2014-12