You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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(),只需要准备好对象列表,一键插入。

额外的实用建议

  1. 用表单类做校验更规范:如果业务逻辑复杂,推荐用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的最佳实践。

  1. 事务保障(可选):如果需要保证“要么所有记录都插入成功,要么全失败”,可以给视图加上@transaction.atomic装饰器,这样插入过程中如果出错,会自动回滚,避免出现部分插入的脏数据。

内容的提问来源于stack exchange,提问作者Gusan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:38:43