如何用Python Django将动态生成行的多行数据插入数据库
动态表单数据无法在Django视图捕获的解决方案
核心问题排查
你的代码存在4个关键问题导致POST数据无法被Django视图捕获:
- 动态生成的下拉框未设置
name属性,Django无法识别该字段 - 标记为
disabled的输入框不会被表单提交,total字段数据无法传递 - 视图中
getlist的参数与表单字段name不匹配(表单用quantity[],视图调用quantity) - 所有表单控件未包裹在
<form>标签内,无法触发表单提交逻辑
分步修复
1. 修正JavaScript动态生成的字段
给下拉框添加name='stock[]',并将total字段的disabled改为readonly(保证数据可提交且用户无法编辑):
// 提前定义renumber变量,避免未声明报错 var renumber = 0; function addItem() { renumber++; var html = "<tr>"; // 给select添加name属性 html += "<td><select class='form-control' name='stock[]'>{% for stock in stocks %}<option class='dropdown-item' value='{{stock.inventoryPart}}'>{{stock.inventoryPart}}</option>{% endfor %}</select></td>"; html += "<td><input type='number' class='form-control' onblur='lineTotal(this);' value='0' name='quantity[]'/></td>"; html += "<td><input type='text' class='form-control' onblur='lineTotal(this);' value='0' name='price[]'/></td>"; // 替换disabled为readonly html += "<td><input type='text' class='form-control' value='0' readonly name='total[]' /></td>"; html += "</tr>"; document.getElementById("addItems").insertRow().innerHTML = html; };
2. 为表单添加正确的包裹结构
将所有表单控件放入<form>标签内,添加CSRF令牌和提交按钮:
<div class="modal-body"> <form method="POST" action="{% url 'customers' %}"> {% csrf_token %} <table class="table order-list table-striped" id="myTable"> <thead> <tr> <th>Item</th> <th>Quantity</th> <th>Price</th> <th>Total</th> </tr> </thead> <tbody id="addItems"> </tbody> </table> <table> <tbody> <tr> <td colspan="5" style="text-align: left;"> <button onclick="addItem();" class="btn btn-sm btn-success" id="sspusd1" type="button"><i class="fa fa-plus"></i>Add Row</button> <button type="submit" class="btn btn-sm btn-primary ml-2">提交订单</button> </td> </tr> </tbody> </table> <input type="hidden" name="Receipttotal" value="1"> </form> </div>
3. 修正Django视图的参数匹配
视图中getlist的参数要与表单字段name完全一致(包括[]):
def customers(request): if request.method == 'POST': if 'Receipttotal' in request.POST: # 匹配表单中的name属性 stocksArr = request.POST.getlist('stock[]') quantityArr = request.POST.getlist('quantity[]') priceArr = request.POST.getlist('price[]') totalArr = request.POST.getlist('total[]') print("---Array Data---") print(stocksArr) print(quantityArr) print(priceArr) print(totalArr) # 示例:遍历数据存入数据库 # for stock, qty, price, total in zip(stocksArr, quantityArr, priceArr, totalArr): # OrderItem.objects.create( # inventory_part=stock, # quantity=int(qty), # price=float(price), # total=float(total) # ) return redirect('order_success') # 提交后重定向到成功页 # GET请求时传递stock数据到模板 stocks = Stock.objects.all() return render(request, 'your_template.html', {'stocks': stocks})
额外注意事项
- 确保
lineTotal函数能正确计算每行总价,更新total字段的值 - 所有动态生成的字段
name必须以[]结尾,Django才能通过getlist获取数组数据 - 必须包含
{% csrf_token %},否则会触发Django的CSRF验证错误
内容的提问来源于stack exchange,提问作者Jordan Kinobe
相关产品推荐
相关产品推荐

