Skip to main content
 首页 » 编程设计

python之基数为 10 的 int() 无效文字 : '' when saving modified modelformset

2025年05月04日12artech

我有一个 modelform 表单集,允许用户添加空行、通过 AJAX 删除现有行并使用 jQuery sortable 重新排列行。

添加/重新排列都只是在表单上设置值,并作为 formset.save() 的一部分保存。

添加新行机制生成最后一个现有行的克隆,并生成正确的输入名称,例如:form-0-id。

如前所述,删除操作调用 AJAX,然后在成功时从 DOM 中删除该行。

重新排列设置了一个隐藏的权重输入,它是模型的一部分。

按下“保存”后,将按顺序发生以下情况:

  1. 去除所有完全空白的行
  2. 将#id_form-TOTAL_FORMS 设置为正确的值
  3. 重置每行每个输入的名称属性,使它们按顺序排列,以防止因删除而产生间隙。
  4. 提交表格。

据我从 console.log 中可以看出,上述步骤都按预期执行,但是我遇到错误的一种情况是:

  1. 有 5 行
  2. 将值添加到第 6 行
  3. 删除任何预先存在的行
  4. 点击保存

我得到 invalid literal for int() with base 10: ''

具体来说,此错误是从以下位置触发的:

lib/python2.7/site-packages/django/db/models/fields/__init__.py in get_prep_value 
    return int(value) ... 
    Local vars: 
        Variable    Value 
        self    <django.db.models.fields.AutoField: id> 
        value   u'' 

我不太明白为什么会失败,我认为自动字段的全部意义在于设置一个值(如果尚未设置)。

我也有些困惑,因为整个表单都可以很好地添加新行,只要在保存整个表单之前不发生删除即可。

表单是否以某种方式记住不同的输入名称属性并尝试更新现有记录而不是保存新记录?

这是来自失败请求的 POST 数据:

Variable    Value 
form-INITIAL_FORMS      u'6' 
form-TOTAL_FORMS        u'3' 
form-MAX_NUM_FORMS      u'' 
form-0-id               u'38' 
form-0-weight           u'0' 
form-0-disk_space       u'1' 
form-0-price_per_month  u'1' 
form-0-embedded_html    u'1' 
form-1-id               u'45' 
form-1-weight           u'3' 
form-1-disk_space       u'2' 
form-1-price_per_month  u'2' 
form-1-embedded_html    u'2' 
form-2-id               u'' 
form-2-weight           u'6' 
form-2-disk_space       u'3' 
form-2-price_per_month  u'3' 
form-2-embedded_html    u'3' 

所以它似乎在 form-2-id 上尝试设置字段值失败,而不是让自动完成它的工作。

下面是成功提交的 POST 数据,我只是加载了表单,添加了一个新行,然后保存了。

Variable            Value 
form-INITIAL_FORMS      u'2' 
form-TOTAL_FORMS        u'3' 
form-MAX_NUM_FORMS      u'' 
form-0-id               u'38' 
form-0-weight           u'0' 
form-0-disk_space       u'1' 
form-0-price_per_month  u'1' 
form-0-embedded_html    u'1' 
form-1-id               u'48' 
form-1-weight           u'1' 
form-1-disk_space       u'2' 
form-1-price_per_month  u'2' 
form-1-embedded_html    u'2' 
form-2-id               u'' 
form-2-weight           u'2' 
form-2-disk_space       u'3' 
form-2-price_per_month  u'3' 
form-2-embedded_html    u'3' 

据我所知,一切都与失败的请求相同,新行的 ID 为空。

完整追溯:http://pastebin.com/AvegYgJA (对 SO 来说太大了)

复制粘贴模式回溯 http://pastebin.com/9R68M6YX

解决方案:

根据下面 Daniel Roseman 的回答,我只需要设置 id_form-INITIAL_FORMS 来匹配更新的行数。我没有在删除时递减初始表单,而是在提交表单之前将以下内容添加到我的 JS 中:

$('#id_form-INITIAL_FORMS').val(this.form.find('span.row-id input[value!=""]').length); 

从而永远解决问题!

请您参考如下方法:

我认为问题是当您删除表单时,您的 JS 没有修改 form-INITIAL_FORMS 的值。正因为如此,Django 认为您的新表单实际上是一个更新,而不是添加,并尝试修改现有的数据库行 - 但当然您对该行有一个空白 ID。尝试在删除中递减 form-INITIAL_FORMS。