第五天.权限批量录入/更新、信号、Django日志配置
1. 角色、菜单、权限的增删该查
1. ModelForm增删改查
2. 增加和编辑使用同一个视图函数
Form()
1. 生成获取用户输入的标签
2. 对用户输入的内容做校验
3. 保留输入的内容同时展示错误提示信息
ModelForm()
1. 不需要自己写类中字段
2. 编辑的时候可以使用instance参数直接把要修改的实例传到form表单
1. 生成获取用户输入的标签时能够把instance的属性直接当成默认值
2. POST提交的时候可以直接调用save()保存数据
FormSet()
from django.forms import formset_factory
ModelFormSet()
from django.forms import modelformset_factory ORM复习(对象关系映射)
1. 对应关系
ORM 数据库
类 <--> 数据表
属性 <--> 字段
对象 <--> 数据行
2. 爬取icon图标
1. requests
2. beautifulsoup4 3. 权限批量录入
1. 集合的操作
1. 差集、交集、反交集
2. 获取一个Django项目的所有路由
rbac/utils/reload_routes.py
3. 页面上将没有入库的路由数据直接加载到addformset中
4. formset使用的三个要点
1. {{ formsetobj.management_form }} --> 管理form(提交数据的时候告诉后端我提交了多少条数据)
2. 每一条数据中都要有form_obj.id(添加的时候不需要,编辑的时候需要)
3. form表单的那三要素
2. 今日内容
权限的批量操作
项目复杂之后URL有很多
1. 自动根据项目的URL录入路由信息(能自动获取路由别名和URL)
1. Django中的路由
二级路由 --> rbac:menu_list #:号就是分割命名空间的,也就是rbacapp的urls.py中还可以再include包另外的路由
三级路由 --> rbac:menu:menu_list
2. 自动录入写完之后会有三种情况:
1. 权限表里有,项目里面没有
2. 权限表里有,项目里面也有
3. 权限表里没有,项目里面有--如加新功能app 3. formset提交数据三要素
1. form表单
2. submit按钮
3. formset_obj.management_form
4. 因为使用的是Formset而不是ModelFormset所以不能调用save()保存,需要自己手动创建数据
1. 批量录入权限2 1. formset和modelformset的使用 2. 集合的操作 3. 如何巧妙的区分同一个action两次不同的POST请求 2. jQuery中文文档:http://jquery.cuishifeng.cn/ 3. 批量更新权限 1. 页面实现 1. Bootstrap、jQuery 2. 页面更新 1. 两个form表单POST提交数据 永远都唔好低估自己! 不负此生,前程似锦!
一.批量录入权限
我想实现的是利用formset实现的是只要你访问某个url,就能把当前项目里所有的路由:第一部分项目里没有但权限表里没有的放在下图1新增中。第二部分是我权限表和项目里都有的,放在下图2更新权限中。第三部分是我数据库里有但项目里没有的,放在如下图3中,此三图在一个页面实现操作管理。
(1)rbac/utils/reload_routes.py:自动录入脚本
from django.conf import settings
from django.utils.module_loading import import_string #module_loading是加载模块
from django.urls import RegexURLResolver
from collections import OrderedDict #per_namespae是前一个命名空间,pre_url是上一级路由,urlpatterns路由表达式,生成一字典
def recursion_urls(pre_namespace, pre_url, urlpatterns, url_ordered_dict):
for item in urlpatterns:
# 如果是嵌套的URL
if isinstance(item, RegexURLResolver):
if pre_namespace:
if item.namespace:
#如果是嵌套的路由那就拿上一级路由命名空间给它拼起来,如果没有上一级则不用拼接直接赋值
namespace = '{}:{}'.format(pre_namespace, item.namespace,)
else:
namespace = pre_namespace
else:
if item.namespace:
namespace = item.namespace
else:
namespace = None
# 如果还有嵌套的三级、四级...路由就递归的执行
recursion_urls(namespace, pre_url + item.regex.pattern, item.url_patterns, url_ordered_dict)
# 普通URL
else:
if pre_namespace:
name = '{}:{}'.format(pre_namespace, item.name,)
else:
name = item.name
if not item.name:
raise Exception('URL路由中必须设置name属性')
url = pre_url + item.regex.pattern
# 把分析出来的每一条路由都以 命名空间:路由别名 为key 存到有序字典里
url_ordered_dict[name] = {'name': name, 'url': url.replace('^', '').replace('$', '')} def get_all_url_dict(ignore_namespace_list=None):#忽略命名空间的列表作为参数但它是可变类型所以设为none好
"""获取路由中"""
ignore_list = ignore_namespace_list or []
# 生成一个有序的字典
url_ordered_dict = OrderedDict()
# 导入Django的路由配置:import_string是根据一字符串导入的模块
root_url_conf = import_string(settings.ROOT_URLCONF)
# 生成一个空列表
urlpatterns = []
# for循环项目所有的路由--luffy_permission/urls.py中的所有路由列表--一级路由
for item in root_url_conf.urlpatterns:
#如果路由是regexurlresolver嵌套路由类型且命名空间在忽略的列表中就continue跳过这次循环
if isinstance(item, RegexURLResolver) and item.namespace in ignore_list:
continue
urlpatterns.append(item)
# 调用上方的函数分析并收集项目中的路由,None是pre_namespace参数(前一个命名空间--在django的路由里它可以嵌套好几层)
recursion_urls(None, '/', urlpatterns, url_ordered_dict)
return url_ordered_dict
(2)rbac/urls.py中:
#权限批量录入
url(r'^permission_entry/$', views.permission_entry, name='permission_entry'),
(3)rbac/views.py中:
from rbac.utils import permission ,reload_routes
from rbac.forms import RoleForm, MenuForm, PermissionForm
from django.forms import modelform_factory, formset_factory # 权限录入
def permission_entry(request):
# 项目里面所有的路由--当你一访问permission_entry时调用get_all_dict方法
all_urls = reload_routes.get_all_url_dict(ignore_namespace_list=['admin', ])
# 数据库中权限表中存储的所有路由
all_permissions = Permission.objects.all() # 用集合去判断
# 项目中所有路由的集合
project_url_set = set(all_urls.keys())
# 数据库中permission表中的路由集合
db_url_set = set([i.name for i in all_permissions])
# 项目中有,数据库中没有
only_in_project = project_url_set - db_url_set
# 这些路由应该是等待添加到数据库中权限表里面的数据
AddFormset = formset_factory(PermissionForm, extra=0)
add_formset_obj = AddFormset(initial=[v for k, v in all_urls.items() if k in only_in_project])
if request.method == 'POST':
add_formset_obj = AddFormset(request.POST)
if add_formset_obj.is_valid():
# 手动创建permission
objs = (Permission(**item) for item in add_formset_obj.cleaned_data)
Permission.objects.bulk_create(objs)
return redirect(reverse('rbac:permission_entry'))
return render(
request,
'rbac/permission_entry.html',
{'add_formset_obj': add_formset_obj}
)
(4)rbac/templates/rbac/permission_entry.html中:
放三个小面板.
{% extends 'layout.html' %} {% block content %}
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<form action="" method="post">
{% csrf_token %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">添加权限
<button class="btn btn-success btn-xs pull-right" type="submit">添加</button>
</h3>
</div>
<div class="panel-body">
<p>那些只在项目中,还没来得及太能加到permission表中的路由数据</p>
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>title</th>
<th>url</th>
<th>show</th>
<th>name</th>
<th>menu</th>
</tr>
</thead>
<tbody>
{% for form_obj in add_formset_obj %}
{{ add_formset_obj.management_form }}
<tr>
{{ form_obj.id }}
<td>{{ forloop.counter }}</td>
<td>{{ form_obj.title }} <span>{{ form_obj.title.errors.0 }}</span></td>
<td>{{ form_obj.url }}</td>
<td>{{ form_obj.show }}</td>
<td>{{ form_obj.name }}</td>
<td>{{ form_obj.menu }}</td>
</tr>
{% endfor %} </tbody>
</table>
</div>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
3
第五天.权限批量录入/更新、信号、Django日志配置的更多相关文章
- MYSQL-JDBC批量新增-更新-删除
目录 1 概述 2 开启MYSQL服务端日志 3 深入MYSQL/JDBC批量插入 3.1 从一个例子出发 3.2 JDBC的批量插入操作 3.3 两个常被忽略的问题 3.5 误区 4 MYSQL/J ...
- 批量自动更新SVN版本库 - Windows
开发过程中每天都要从SVN代码库里一个一个的update各个项目代码,不仅效率实在是低,也不符合程序员的"懒"精神,由于是在Windows环境做开发,自然就想到了使用bat来实现自 ...
- 批量录入快递地址-快宝地址服务(PHP代码示例)
快递地址写错了怎么办?快递地址写的不详细怎么办?怎么皮批量录入收件人地址?微商怎么批量录入发件人地址?快宝地址清洗,有效的解决了寄送快递时,批量录入收件人信息.发件人信息时,纠正地址数据,不完整地址识 ...
- SqlServer-RBAC五表权限
这只是一个精简的SqlServer-RBAC五表权限,根据自身需求修改即可 --创建数据库-权限CREATE DATABASE RBACGOUSE RBACGO --1.权限表CREATE TABLE ...
- ON DUPLICATE KEY UPDATE单个增加更新及批量增加更新的sql
转: ON DUPLICATE KEY UPDATE单个增加更新及批量增加更新的sql 本文为博主原创,转载请注明出处. 在实际应用中,经常碰到导入数据的功能,当导入的数据不存在时则进行添加,有修改时 ...
- Gitlab用户在组中有五种权限:Guest、Reporter、Developer、Master、Owner
Gitlab权限管理Gitlab用户在组中有五种权限:Guest.Reporter.Developer.Master.Owner Guest:可以创建issue.发表评论,不能读写版本库Reporte ...
- oracle批量新增更新数据
本博客介绍一下Oracle批量新增数据和更新数据的sql写法,业务场景是这样的,往一张关联表里批量新增更新数据,然后,下面介绍一下批量新增和更新的写法: 批量新增数据 对于批量新增数据,介绍两种方法 ...
- Gitlab用户在组中有五种权限
Gitlab用户在组中有五种权限:Guest.Reporter.Developer.Master.Owner Guest:可以创建issue.发表评论,不能读写版本库 Reporter:可以克隆代码, ...
- 第四百零五节,centos7下搭建sentry错误日志服务器,接收python以及Django错误,
第四百零五节,centos7下搭建sentry错误日志服务器,接收python以及Django错误, 注意:版本,不然会报错 Docker >=1.11Compose >1.6.0 通过d ...
随机推荐
- Java实现 LeetCode 715 Range 模块(选范围)
715. Range 模块 Range 模块是跟踪数字范围的模块.你的任务是以一种有效的方式设计和实现以下接口. addRange(int left, int right) 添加半开区间 [left, ...
- Java实现 蓝桥杯 算法提高 判断名次
算法提高 判断名次 时间限制:1.0s 内存限制:256.0MB 问题描述 某场比赛过后,你想要知道A~E五个人的排名是什么,于是要求他们每个人说了一句话.(经典的开头---_-!)得了第1名的人23 ...
- Java实现 蓝桥杯 算法提高 合并石子
算法提高 合并石子 时间限制:2.0s 内存限制:256.0MB 问题描述 在一条直线上有n堆石子,每堆有一定的数量,每次可以将两堆相邻的石子合并,合并后放在两堆的中间位置,合并的费用为两堆石子的总数 ...
- Java实现 蓝桥杯VIP 算法训练 字符串编辑
算法训练 字符串编辑 时间限制:1.0s 内存限制:512.0MB 问题描述 从键盘输入一个字符串(长度<=40个字符),并以字符 '.' 结束.编辑功能有: 1 D:删除一个字符,命令的方式为 ...
- Java实现 LeetCode_0048_RotateImage
package javaLeetCode.medium; public class RotateImage_48 { public static void main(String[] args) { ...
- 实验三 Linux系统用户管理及VIM配置
项目 内容 这个作业属于哪个课程 班级课程的主页链接 这个作业的要求在哪里 作业要求链接接地址 学号-姓名 17041428-朱槐健 作业学习目标 1.学习Linux系统用户管理 2.学习vim使用 ...
- org.apache.maven.plugins:maven-archetype-plugin:RELEASE:generate——解决方案汇总
近期将自己本地的 maven 仓库进行了迁移,idea 的版本也升级到了IntelliJ IDEA 2019.3.3 x64,但是遇到了 Plugins 报红的情况,尝试很多方法,终于解决,现在做一下 ...
- 如何安装 Sublime text 编辑器相关的插件
Sublime是一个伟大的编辑器,具有可靠的基础功能,使编写代码变得愉快.您可以安装一个包管理器,以便于安装插件和添加新功能. 为什么使用包管理器(package manager) 包管理器可以方便地 ...
- nacos基础--客户端下载
对于nacos的作用,我在这里不在过多介绍,不知道的同学可以自行先了解,对于nacos,有官网进行介绍,对于一个初学者来说是一件非常方便的事情. 官网地址:https://nacos.io 但是在下载 ...
- mybatis的缓存2
原文:https://blog.csdn.net/qq_38274974/article/details/100898145 mybatis的缓存分为一级缓存.二级缓存那么,我们为什么要使用缓存呢? ...