django批量修改table_django-formset实现数据表的批量操作
什么是formset
我们知道forms组件是用来做表单验证,更准确一点说,forms组件是用来做数据库表中一行记录的验证。有forms组件不同,formset是同科同时验证表中的多行记录,即formset是做表单批量验证的组件。
批量添加
首先要实例化formset对象,对象初始化时需要提供操作表的forms表单类,参数extra用来显示验证几行数据。将实例化的formset对象传递给前端页面,前端模板通过两层循环:第一层循环form,第二层循环form中的字段。当GET请求时,直接将实例化的formset对象传递给前端。当POST请求时,批量验证表单,当所有数据都没有问题时,后台数据库保存数据。
后台保存数据时,有两种方式:第一种方式简洁,但是无法捕获字段唯一约束的错误;因此使用formset批量添加数据时最好使用第二中方式,手动捕获唯一约束错误信息并交给formset送到前端页面显示。
models.Permission.objects.create(**row)
obj = models.Permission(**row) | obj.save()
唯一约束错误信息捕获的过程,需要使用obj.validate_unique()判断该对象是否满足唯一约束,如果不满足则通过异常捕获操作,捕获异常信息。通过formset.errors[i].update(e)把错误信息放入formset中送到前端页面显示。之所以这样做,是因为通过forms组件的验证时无法捕获唯一约束的错误。因此这里通过手动收集错误信息并放入forset中。
此外,如果前端页面渲染的表单没有填写数据,直接提交是不会报错的。formset默认只要不改动字段就不会对该行数据做验证。只要填写一个字段,该行数据则会做表单验证。
# views.py
def multi_add(request):
"""
批量添加
:param request:
:return:
"""
formset_class = formset_factory(MultiPermissionForm, extra=2)
if request.method == 'GET':
formset = formset_class()
return render(request, 'multi_add.html', {'formset': formset})
formset = formset_class(data=request.POST)
if formset.is_valid():
flag = True
# 检查formset中没有错误信息,则讲用户提交的数据获取到。
post_row_list = formset.cleaned_data
for i in range(0, formset.total_form_count()):
row = post_row_list[i]
if not row:
continue
try:
obj = models.Permission(**row)
obj.validate_unique() # 检查当前对象在数据库是否存在唯一的异常。
obj.save()
except Exception as e:
formset.errors[i].update(e)
flag = False
if flag:
return HttpResponse('提交成功')
else:
return render(request, 'multi_add.html', {'formset': formset})
return render(request, 'multi_add.html', {'formset': formset})
前端模板通过两层循环:第一层循环formset得到每一个form,第二层循环form得到每一个字段。与forms组件使用一样,需要手动添加form表单和input提交数按钮及csrf_token跨域伪造请求。此外,使用formset,还需要增加{{ formset.management_form }} , 使用哪个formset就增加哪个formset.management_form.
# multi_add.html
{% csrf_token %}
{{ formset.management_form }}
标题URLNAME菜单父权限
{% for form in formset %}
{% for field in form %}
{{ field }} {{ field.errors.0 }}
{% endfor %}
{% endfor %}
批量编辑
批量编辑和批量增加大体是一致的,但是存在不同的使用区别。实例化formset对象时默认extra=1,需要手动修改为extra=0;GET请求,页面需要显示默认值,通过参数initial赋值列表内部嵌套字典的数据结构的数据。且需要传递每行数据的id,告诉formset需要修改的数据id。此时使用的forms类相比批量添加使用的类多一个id字段,id = forms.IntegerField( widget=forms.HiddenInput()),默认隐藏的字段,前端页面不显示。
同理也会遇到唯一约束错误,使用循环和反射为每个字段做数据更新赋值,然后再提交数据库保存。
def multi_edit(request):
formset_class = formset_factory(MultiUpdatePermissionForm, extra=0)
if request.method == 'GET':
formset = formset_class(
initial=models.Permission.objects.all().values('id', 'title', 'name', 'url', 'menu_id', 'pid_id'))
return render(request, 'multi_edit.html', {'formset': formset})
formset = formset_class(data=request.POST)
if formset.is_valid():
# 检查formset中没有错误信息,则讲用户提交的数据获取到。
post_row_list = formset.cleaned_data
flag = True
for i in range(0, formset.total_form_count()):
row = post_row_list[i]
if not row:
continue
permission_id = row.pop('id')
try:
permission_object = models.Permission.objects.filter(id=permission_id).first()
for key, value in row.items():
setattr(permission_object, key, value)
permission_object.validate_unique()
permission_object.save()
except Exception as e:
formset.errors[i].update(e)
flag = False
if flag:
return HttpResponse('提交成功')
else:
return render(request, 'multi_edit.html', {'formset': formset})
return render(request, 'multi_edit.html', {'formset': formset})
前端模板循环显示每个字段时,要判断是否是第一个id字段,如果是第一个就直接{{field}},页面将不会显示。
{% csrf_token %}
{{ formset.management_form }}
标题URLNAME菜单父权限
{% for form in formset %}
{% for field in form %}
{% if forloop.first %}
{{ field }}
{% else %}
{{ field }} {{ field.errors.0 }}
{% endif %}
{% endfor %}
{% endfor %}
标签:form,request,django,forms,数据表,id,formset,row
来源: https://www.cnblogs.com/liuxu2019/p/11992573.html
django批量修改table_django-formset实现数据表的批量操作相关推荐
- django批量修改table_django formset实现数据表的批量操作的示例代码
什么是formset 我们知道forms组件是用来做表单验证,更准确一点说,forms组件是用来做数据库表中一行记录的验证.有forms组件不同,formset是同科同时验证表中的多行记录,即form ...
- django批量修改table_Django 使用 modelformset 组件批量修改表单数据
1.models.py: class StudentStudyRecord(models.Model): ''' 学生学习记录 ''' student = models.ForeignKey(verb ...
- django批量修改table_Django 数据库表多对多的创建和增删改查
前面已经学习了在Django里面如何对单表的操作,同时也学习了1对多(单个外键)的表的操作.接下来,我们看看多对多(多个外键)的关系如何创建和管理. 比如说,我们有一个主机表,也有一个应用程序表,一个 ...
- django批量修改table_Django修改桥表(Django modify bridge table)
Django修改桥表(Django modify bridge table) 我的django应用程序中有两个模型,事件/用户,它们具有多对多的关系. 活动可以有很多与会者(用户). 用户可以参加很多 ...
- django批量修改table_django restframework 多对多的批量修改,基于逻辑删
模型: class LogisticQuerySet(QuerySet): def delete(self): self.update(is_delete=True) class BookManage ...
- MySQL批量修改数据库中的数据表名称
1.一种使用存储过程解决,结果,总是如下提示 Expression #3 of SELECT list is not in GROUP BY clause and contains n 2.使用 CO ...
- Django 之 Models(Models 模型 数据表关系)
Models 模型 ORM django连接数据库 models类的使用 定义和数据库表映射的类 字段常用参数 数据库的迁移 数据相关操作 查看数据库中的数据 查找数据 添加数据 常见查找方法 数据库 ...
- 批量修改table和index 的表空间
由于开发人员把ess 项目下的大部分对象放到user 表空间中,用imp/exp 导入正式库后,ess用户的对象还是在users 表空间中.为了把ESS 的对象放到ess 默认的表空间ess中,我按如 ...
- 反思一次线上bug的修改:没法看数据表的一次线上问题处理
线上问题:点击保存后,关联的后台显示不了修改的数据 困难点:线上数据库连接不了需要vpn 解决方法: 沟通进行确定数据表的数据,确定数据保存存在问题 根据master进行新建分支fix-bug ,排查 ...
最新文章
- 高性能集群软件Keepalived之基础知识篇
- 我能使用这个Intent吗?
- 深圳网络推广谈论网站收录后的内容还能不能修改?
- 解析远程服务器响应错误,远程服务器返回一个意外的响应:(400)错误的请求,WCF...
- boost::spirit模块实现演示自定义的、用户定义的类型如何作为标记值类型轻松地与词法分析器集成
- 前端做CRM管理系统是做什么_代办行业的CRM客户关系管理系统应该是什么样子的?...
- 为什么数据科学家需要承担开发运维的工作?
- 超实用的脚本——检查oracle数据库是否存在潜伏的比特币勒索病毒
- Eclipse下PHP开发 插件安装
- 关于备考软考过程中历年真题的说明
- JAVA实现网页版斗地主_使用Java实现简单的斗地主案例
- 解决Unity TextMeshPro 不能显示中文问题
- DDR3各个频率详解
- iOS之推荐六款不错的 iOS 15 Safari 浏览器扩展
- python处理excel——创建excel工作簿和工作表并录入信息(openpyxl库)
- SQLite3 获取最小可用ID,ID无需包含1
- DLbest系列1——GAN生成对抗网络2
- pg中多值列_PostgreSQL中列的statistics属性
- 连连看修改(golang)
- 前端:使用BootStrap搭建一个简单的网页
热门文章
- oracle中xml如何存储过程,oracle存储过程生成xml文件
- oracle错误12637,TNS-12537 TNSconnection closed ORA-609错误处理
- 鸿蒙思维和小央美,中心路汝南路站附近艺术培训
- zabbix触发器表达式
- [原创]前端工作了一段时间经验总结,献给做前端的同学
- day3-python学习笔记(二)list(数组)
- .NET CORE在ubuntu1604上运行
- 将自己的女朋友的话和视频做为启动音乐和启动动画(XP)
- [Leetcode][第1025题][JAVA][除数博弈][数学][递推]
- matlab如何找出最小的数据,读取数据并找出全部数据的最大值和最小值