Django中如何循环request.POST数据并按行写入数据库?
解决动态表单多组数据提交冗余问题
你当前的代码用了多层嵌套循环,这会让每个description和所有length、width、depth、quantity做笛卡尔积组合,自然会生成大量冗余数据。正确的做法是按表单提交的顺序,把每组对应的字段值一一匹配,而不是互相交叉组合。
修正后的代码
descriptions = request.POST.getlist('description') lengths = request.POST.getlist('lengthx') widths = request.POST.getlist('widthx') depths = request.POST.getlist('depthx') quantitys = request.POST.getlist('qtyx') # 按索引把每组对应字段打包,循环创建数据 for desc, leng, wid, dep, qty in zip(descriptions, lengths, widths, depths, quantitys): QuoteItem.objects.create( qdescription=desc, qlength=leng, qwidth=wid, qdepth=dep, qquantity=qty, quote_number=quotenumber, )
原理说明
request.POST.getlist()返回的列表是按照表单中字段的提交顺序排列的,比如第一组的description是列表第一个元素,对应的第一组lengthx也是lengths列表的第一个元素。用zip()函数可以把这五个列表中相同位置的元素打包成元组,循环每个元组就能得到一组完整的对应数据,这样写入数据库的就是每组正确的单行数据,不会产生冗余。
额外提醒
如果动态表单允许用户删除部分行,可能会出现五个列表长度不一致的情况,这时候可以用itertools.zip_longest替代zip,并处理空值(比如跳过空数据的组),示例如下:
from itertools import zip_longest for desc, leng, wid, dep, qty in zip_longest(descriptions, lengths, widths, depths, quantitys, fillvalue=None): # 跳过空数据的组 if not all([desc, leng, wid, dep, qty]): continue QuoteItem.objects.create( qdescription=desc, qlength=leng, qwidth=wid, qdepth=dep, qquantity=qty, quote_number=quotenumber, )
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

