Django formset - 仅在没有初始数据集时显示额外字段?

时间:2011-09-09 14:32:55

标签: django django-forms

我有一个显示多个Formset的页面,每个Formset都有一个前缀。使用formset_factory默认选项创建表单集,包括extra=1。可以使用JavaScript添加或删除行。

如果用户正在添加新数据,则会显示一个空白行。完美。

如果用户添加了数据但表单验证失败,在这种情况下,使用MyFormset(data, prefix='o1-formsetname')等填充POST数据的表单集,只显示他们输入的数据。再次,完美。 (o1等是动态生成的,每个o对应一个“选项”,每个“选项”可能有多个表单集。

但是,如果用户正在编辑现有数据,则在该情况下,视图使用MyFormset(initial=somedata, prefix='o1-formsetname')填充表单集,其中somedata是来自数据库中模型的数据序列的列表,在此数据之后插入空白行。除非用户使用JavaScript明确添加一行,否则我不希望显示空行。

如果设置了初始数据,是否有任何简单的方法可以阻止formset显示额外的行?我在第三个例子中使用initial的原因是,如果我只是使用MyFormset(somedata, prefix='o1-formsetname')传递数据,我必须做一个额外的步骤,将所有数据重新格式化为POSTdata样式的dict,包括每个字段的前缀,例如o1-formsetname-1-price: x等,以及计算管理表单数据,这会增加一大堆复杂性。

一种解决方案可能是在将formset发送到模板并手动删除行之前拦截它,但extra_forms属性似乎不可写,并将extra设置为0没有任何区别。我也可以让JavaScript检测这种情况并删除该行。但是我不禁想到,我错过了一些明显的东西,因为我想要的行为对我来说似乎是明智的预期行为。

感谢。

2 个答案:

答案 0 :(得分:5)

max_num关键字参数用于formset_factory

MyFormset = formset_factory([...], extra=1, max_num=1)

有关详细信息,请查看limiting the maximum number of forms

一个障碍:大概你希望能够处理多个空白表格。这不太难;只需确保在POST处理方使用max_num关键字参数。

答案 1 :(得分:3)

我想出了一个适用于Django 1.1的解决方案。我创建了一个BaseFormSet的子类,它覆盖了total_form_count方法,这样,如果存在初始表单,则总计不包含额外的表单。或许有点破解,也许有一个我找不到的更好的解决方案,但它确实有效。

class SensibleFormset(BaseFormSet):
    def total_form_count(self):
        """Returns the total number of forms in this FormSet."""
        if self.data or self.files:
            return self.management_form.cleaned_data[TOTAL_FORM_COUNT]
        else:
            if self.initial_form_count() > 0:
                total_forms = self.initial_form_count()
            else:
                total_forms = self.initial_form_count() + self.extra
            if total_forms > self.max_num > 0:
                total_forms = self.max_num
            return total_forms