0

I've created a CreateView form with a Parent (named 'Entrada') model and (multiple) Children models (named 'BalaMateriesPrimeres') as formset. Those formset are created dynamically with a JS I've created so I can add as many children I want (instead of adding one by one with elo80ka dynamic formset plugin). But the problem is that the formset is invalid. When print the formset at the 'def post' method, I get the html tags but the 'value' field of each one is empty. This is the relevant code:

forms.py

class EntradaForm(ModelForm):
    class Meta:
        model = Entrada
        exclude = ()


class BalaMateriesPrimeresForm(ModelForm):
    class Meta:
        model = BalaMateriesPrimeres
        fields = ['quilos', 'material', 'cost_unitari']

BalaMateriesPrimeresFormSet = inlineformset_factory(Entrada, BalaMateriesPrimeres, form=BalaMateriesPrimeresForm, can_delete=True, extra=1)

views.py

class EntradaCreateUpdateView(LoginRequiredMixin, UpdateView):
    model = Entrada
    form_class = EntradaForm
    formset_class = BalaMateriesPrimeresFormSet

    def get_context_data(self, **kwargs):
        data = super(EntradaCreateUpdateView, self).get_context_data(**kwargs)
        if self.request.POST:
            data['bales_materies_primeres'] = BalaMateriesPrimeresFormSet(self.request.POST)
            data['materials'] = Material.objects.all()
        else:
            data['bales_materies_primeres'] = BalaMateriesPrimeresFormSet()
            data['materials'] = Material.objects.all()
        return data

    def get_object(self):
        self.creating = 'pk' not in self.kwargs
        if self.creating:
            return None # Sucess
        else:
            obj = super().get_object()
            return obj

    def post(self, request, *args, **kwargs):
        form = self.get_form()
        formset = BalaMateriesPrimeresFormSet(request.POST, prefix='bales_materies_primeres')
        if form.is_valid() and formset.is_valid():
            return self.form_valid(form, formset)
        else:
            return self.form_invalid(form, formset)

    def form_valid(self, form, formset):
        self.object = form.save()
        for fmset in formset:
            fmset.save()
    return super(EntradaCreateView, self).form_valid(form)

form.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"> Crear una nova entrada</h2>
<!-- Formulari d'entrada  -->
<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>
<!-- /Formulari d'entrada -->
<hr>

<!-- Formulari de Material -->
<div class="form-group form-material-box row form-0">
  <div class="col-3 text-center">
    <label>Pes aproximat: </label>
    <input type="number" id="kg_0">
  </div>
  <div class="col-3 text-center">
    <label>Bales a crear: </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">Crea</button>
  </div>

  <!-- Nested forms with desired number of boxes -->
  <div id="nested_forms_0">
    {{ bales_materies_primeres.management_form }}
    {% for bala in bales_materies_primeres %}
    <div class="row" id="box_0">
      <div class="col-3 text-center">
        <h5>Bala #1: </h4>
      </div>
      <div class="col-2 text-center">
        {{ bala.quilos }}
      </div>
      <div class="col-2 text-center" >
        {{ bala.material }}
      </div>
      <div class="col-2 text-center" >
        {{ bala.cost_unitari }}
      </div>
      <div class="col-3 text-center">
        <button type="button" id='remove_box_0' class="btn btn-danger">Elimina Bala</button>
      </div>
      {% endfor %}
    </div> <!-- /Bala form -->
  </div>  <!-- /Nested forms -->
</div>  <!-- /Form -->
<!-- /Formulari de Material -->
<p>
  <input id="crear" class="btn btn-secondary btn-lg btn-block btn-option btn-form" type="submit" value="Crear" />
</p>

javascript code: https://pastebin.com/i87mqAaG

What I've tried:

-Yes, I've checked the TOTAL_FORMS value in the dev tools of Chrome. Also all the info is there as Django debug toolbar says

-When I print the formset right after getting it, it returns the HTML structure without values

-If I print the kwargs at the def post method I don't get anything.

I don't know what I'm missing but I had this problem for days.

DavidMM
  • 187
  • 3
  • 11

0 Answers0