2

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

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

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

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

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

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

  1. 剥离任何完全空白的行
  2. 将 #id_form-TOTAL_FORMS 设置为正确的值
  3. 重置每行上每个输入的 name 属性,使它们是连续的,以防止由于删除而导致的间隙。
  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因此,尝试设置字段值似乎失败了,而不是让 auto 来完成它的工作。

下面是来自成功提交的 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);

从而永远解决问题!

4

1 回答 1

1

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

于 2013-04-02T10:24:18.750 回答