简短版:动态创建多个表单集只会保存 extra 属性中指定的格式集,而不是我所拥有的格式集。
长版:我正在使用Django完成我的第一个项目,我将创建一个包含Parent和Child表单的CreateView。我需要创建用户想要的尽可能多的嵌套子窗体,所以我在Javascript中创建了一个添加/删除子窗体的小代码。这很好。
问题是:我只能保存我在 extra 属性中指定的表单。如果我说'3',它会创建3个Child表单,即使我创建/删除Child表单,我也可以保存3个表单。如果我说'1',我可以创建10,但只能保存1.似乎我在模板中遗漏了一些东西,但我不知道是什么。这是相关的代码:
forms.py
class ParentForm(ModelForm):
class Meta:
model = Parent
exclude = ()
class ChildForm(ModelForm):
class Meta:
model = Child
fields = ....
ChildFormSet = inlineformset_factory(Parent, Child, form=ChildForm, can_delete=True, extra=1)
views.py
class ParentCreateView(LoginRequiredMixin, CreateView):
model = Entrada
fields = ...
def get_context_data(self, **kwargs):
data = super(ParentCreateView, self).get_context_data(**kwargs)
if self.request.POST:
data['child_form'] = ChildFormSet(self.request.POST)
data['materials'] = Material.objects.all()
else:
data['child_form'] = ChildFormSet()
data['materials'] = Material.objects.all()
return data
def form_valid(self, form):
context = self.get_context_data()
child_form = context['child_form']
with transaction.atomic():
self.object = form.save()
if child_form.is_valid():
child_form.instance = self.object
child_form.field1 = self.object.id
child_form.save()
return super(ParentCreateView, self).form_valid(form)
template.html
<form class="own-form" action="" method="post">
{% csrf_token %}
{% for hidden_field in form.hidden_fields %}
{{ hidden_field }}
{% endfor %}
<h2 class="text-center text-header"> New Entry</h2>
<div class="form-group">
{% for field in form.visible_fields %}
<div class="form-group row">
<div class="col-4 text-center">{{ field.label_tag }}</div>
<div class="col-8">{{ field }}</div>
{% if field.help_text %}
<small class="form-text text-muted">{{ field.help_text }}</small>
{% endif %}
</div>
{% endfor %}
</div>
<hr>
<div class="form-group form-material-box row form-0">
<div class="col-3 text-center">
<label>Total weight: </label>
<input type="number" id="kg_0">
</div>
<div class="col-3 text-center">
<label>Boxes to create: </label>
<input type="number" id="num_boxes_0">
</div>
<div class="col-3 text-center">
<label>Material: </label>
<br>
<select name="item_id" id="material_0">
{% for material in materials %}
<option value="{{ forloop.counter }}">{{ material }}</option>
{% endfor %}
</select>
</div>
<div class="col-3 text-center">
<button type="button" id="create_boxes_0" class="btn btn-danger">Create</button>
</div>
<!-- Nested forms with desired number of boxes -->
<div id="nested_forms_0">
<div class="row" id="box_0">
{% for bala in bala_form %}
<div class="col-3 text-center">
<h5>Bala #1: </h4>
</div>
<div class="col-2 text-center">
{{ bala.kg }}
</div>
<div class="col-2 text-center" >
{{ bala.material }}
</div>
<div class="col-2 text-center" >
{{ bala.box_price }}
</div>
<div class="col-3 text-center">
<button type="button" id='remove_box_0' class="btn btn-danger">Remove box</button>
</div>
{% endfor %}
</div>
</div>
</div>
<p>
{{ child_form.management_form }}
<input id="create" class="btn btn-secondary btn-lg btn-block btn-option btn-form" type="submit" value="Crear" />
</p>
修改:
javascript相关代码
// Adds the difference between desired boxes and current boxes
function add_boxes(form_id, total, num){
for (let i = total; i != total+num; i++) {
var element = $('#nested_forms_' + form_id + "> :first-child ").clone().css('display', 'none');
element.appendTo('#nested_forms_' + form_id).show('250');
};
$('#id_child-TOTAL_FORMS').val(num + total);
};
// Removes every unneeded boxes
function remove_boxes(form_id, total){
$('#nested_forms_' + form_id).children().each(function(){
if ($(this).index() >= total) {
$(this).fadeTo(150, 0).slideUp(150, function(){
$(this).remove();
});
}
});
$('#id_child-TOTAL_FORMS').val(total);
}
我缺少什么?
更新 我已经从模板中打印了传递给Django的信息。当我创建超过额外的表单时,似乎只是获取没有任何值的空表单。比较我在动态创建3个表单时的差异(左)和硬编码3作为 extra 值(右)显示它(bales-materies-primeres是Child的名称):