多个表单集仅将表单集的数量保存在“额外”属性中:为什么?

问题描述 投票:0回答:1

简短版本:动态创建多个表单集只能保存额外属性中指定的多少表单集,而不是像我一样多。

长版本:我正在用Django做我的第一个项目,我要创建一个带有Parent和Child表单的CreateView。我需要创建用户想要的尽可能多的嵌套子窗体,所以我在Javascript中创建了一个添加/删除子窗体的小代码。这工作正常。

问题是:我只能保存我在额外属性中指定的多个表单。如果我说'3',它会创建3个Child表单,即使我创建/删除Child表单,我也可以保存3个表单。如果我说'1',我可以创建10,但只能保存1.似乎我在模板中遗漏了一些东西,但我不知道是什么。这是相关的代码:

forms.朋友

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.朋友

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作为额外值(右)显示它(bales-materies-primeres是Child的名称):

https://www.diffchecker.com/XskfB9y3

django
1个回答
0
投票

您的Javascript需要修改管理表单中form-TOTAL_FORMS字段的值。见formsets documentation

© www.soinside.com 2019 - 2024. All rights reserved.