Django:如何将初始值设置为 formset 的 empty_form?

Django: How can I set initial values to formset's empty_form?

我只想知道如何将初始值设置为 empty_form

我确实为额外的表单创建了带有初始值的内联没有问题,但是,当用户单击 Add 按钮时,我希望它具有初始值的字段显示为空, 我希望它与额外形式具有相同的初始值。

如何让 empty_form 填充初始数据?

提前致谢。

我遇到了类似的问题,最终对我有用的方法是使用 Django Dynamic Formset。 DDF 所做的不是使用空表单来创建新的表单集,而是使用 extra_forms 之一作为模板。默认行为是在将 HTML 插入 DOM 之前清除 extra_form 中的所有字段值,但您可以使用 keepFieldValues 设置来指定您想要保持。

在我的例子中,我想保留所有隐藏字段值:

$(function() {
    $('#myForm_table tbody tr').formset({
        keepFieldValues: 'input:hidden',
        }
    });
});

当然,如果您愿意,您可以绕过 Django 动态表单集并使用 Javascript 实现您自己的 add/delete 代码。

Django 并没有真正提供为空表单设置初始值的方法。我找到了几种解决此问题的方法:

  1. 在 javascript 中动态设置字段值。
  2. 为您的表单集覆盖 empty_form 属性。

示例:

formset = formset_factory(MyClass, **kwargs)
empty = formset.empty_form    
# empty is a form instance, so you can do whatever you want to it
my_empty_form_init(empty_form)
formset.empty_form = empty_form

接受的答案对我不起作用,希望这对以后的人有所帮助,这是我的解决方案:

  1. 基于 BaseInlineFormSet
  2. 创建一个新的 class
  3. 覆盖empty_form
  4. 使用 inlineformset_factory(formset=YourBaseInlineFormSet)
  5. 创建一个 FormSet
  6. 创建一个表单集实例并将参数传递给表单集实例上的初始值
  7. 像往常一样在HTML上添加字段

我使用了 BaseInlineFormSet,但可能会与其他类型的 FormSet

一起使用

verification 是我的示例的字段名称。

forms.py

class YourBaseInlineFormSet(forms.BaseInlineFormSet):
    @property
    def empty_form(self):  # This is almost the same as Django 3.1 code
        form = self.form(
            auto_id=self.auto_id,
            prefix=self.add_prefix("__prefix__"),
            empty_permitted=True,
            use_required_attribute=False,
            initial={"verification": self.initial_extra[0]["verification"]},  # This is the extra parameter
            **self.get_form_kwargs(None),
        )
        self.add_fields(form, None)
        return form


YourFormSet = forms.inlineformset_factory(
    SomeObject,
    SomeRelatedObject,
    fields="__all__",
    widgets={"verification": forms.HiddenInput},
    formset=YourBaseInlineFormSet,
)

views.py

from .forms import YourFormSet

def your_view(request):
    formset = YourFormSet(
        data=request.POST or None,
        instance=object,
        queryset=object.related_objects.all()
        initial=[{"verification": verification} for a in range(FormSet().total_form_count())],
    )
    return render(request, template, context={'formset': formset})

template.html

<div id="empty_form" style="display:none">
    {{ formset.empty_form }}
</div>

正在使用 Django 3.1

至少有一种方法可以做到这一点:在 model Field.

上指定 default

当然,这可能会产生副作用,具体取决于您对模型的实施。