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

时间:2018-05-02 08:09:12

标签: django

简短版:动态创建多个表单集只会保存 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的名称):

https://www.diffchecker.com/XskfB9y3

1 个答案:

答案 0 :(得分:0)

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