如何在Django中批量插入多条记录?附现有代码示例
搞定Django批量插入Transaksi记录的方案
嘿,我来帮你解决这个批量插入的问题!首先得理清楚:你前端用{% for t in trans %}循环生成了多个同名的表单字段(比如多个name="kode_pem"和name="nominal"),提交后Django的request.POST会把这些同名字段的值打包成列表,但你现在的代码直接把整个列表赋值给单个Transaksi实例,这肯定没法生成多条记录,得调整成批量处理的逻辑。
第一步:修改views.py的核心代码
直接逐个创建实例再save()虽然能跑,但效率极低(每save一次就发一次SQL请求),推荐用Django自带的bulk_create()方法,一次性把多条记录插入数据库,性能拉满。
修改后的代码如下,我加了注释和一些实用的校验逻辑:
from django.shortcuts import redirect, render from django.db import transaction # 可选,用于事务保障 from .models import Transaksi def input_transaksi(request): if request.method == 'POST': # 用getlist()获取所有同名字段的列表,而不是直接取dict值 kode_pem_list = request.POST.getlist('kode_pem') nominal_list = request.POST.getlist('nominal') # 先校验两个列表长度是否一致,避免出现"kode_pem有3个,但nominal只有2个"的情况 if len(kode_pem_list) != len(nominal_list): # 这里可以根据需求返回错误提示,比如跳回表单页+错误信息 return redirect('你的表单页面URL名称') # 准备要批量插入的对象列表 transaksi_batch = [] for kode_pem, nominal in zip(kode_pem_list, nominal_list): # 先过滤空值,避免插入无效数据 clean_kode = kode_pem.strip() clean_nominal = nominal.strip() if not clean_kode or not clean_nominal: continue # 把nominal转成整数(因为你的模型里是IntegerField),处理可能的格式错误 try: nominal_int = int(clean_nominal) transaksi_batch.append(Transaksi(kode_pem=clean_kode, nominal=nominal_int)) except ValueError: # 遇到非数字的nominal可以选择跳过,或者返回错误提示 continue # 批量插入所有有效记录 if transaksi_batch: Transaksi.objects.bulk_create(transaksi_batch) # 插入完成后跳转到你想要的页面,比如记录列表页 return redirect('transaksi_list') # 替换成你的实际URL名称 # GET请求的话返回表单页面(如果需要的话) return render(request, '你的表单模板.html')
第二步:确认前端表单的name属性正确
前端循环生成的表单字段,一定要保证name属性是kode_pem和nominal,比如:
{% for t in trans %} <div class="form-group"> <label>Kode PEM</label> <input type="text" name="kode_pem" placeholder="输入Kode" required> </div> <div class="form-group"> <label>Nominal</label> <input type="number" name="nominal" placeholder="输入金额" required> </div> {% endfor %}
这样提交后,request.POST.getlist()才能正确拿到所有字段的列表值。
划重点:为什么用bulk_create()?
- 性能爆炸:
bulk_create()会把多条插入请求合并成一条SQL语句(主流数据库都支持),比逐个save()减少N次数据库交互,数据量越大,效率提升越明显。 - 代码更简洁:不需要循环调用
save(),只需要准备好对象列表,一键插入。
额外的实用建议
- 用表单类做校验更规范:如果业务逻辑复杂,推荐用Django的
Form或ModelForm来做数据校验,比如:
from django import forms class TransaksiForm(forms.Form): kode_pem = forms.CharField(max_length=2) nominal = forms.IntegerField(min_value=0)
然后在视图里循环校验每一组数据,这样错误提示更友好,也更符合Django的最佳实践。
- 事务保障(可选):如果需要保证“要么所有记录都插入成功,要么全失败”,可以给视图加上
@transaction.atomic装饰器,这样插入过程中如果出错,会自动回滚,避免出现部分插入的脏数据。
内容的提问来源于stack exchange,提问作者Gusan
相关产品推荐
相关产品推荐

