Использование нескольких наборов форм сохраняет только количество наборов форм в атрибуте «extra»: Почему?

Укороченная версия: создание динамически нескольких наборов форм сохраняет только то количество наборов форм, которое указано в атрибуте дополнительный, а не столько, сколько я.

Длинная версия: Я делаю свой первый проект с Django, и мне нужно создать CreateView с родительскими и дочерними формами. Мне нужно создать столько вложенных дочерних форм, сколько хочет пользователь, поэтому я создал небольшой код в Javascript, который добавляет / удаляет дочерние формы. Это нормально работает.

Проблема в том, что я могу сохранить только столько форм, сколько я указал в атрибуте дополнительный. Если я скажу «3», будет создано 3 дочерних формы, и я могу сохранить 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, как показывает значение дополнительный (справа) (bales-materies-primeres - это имя ребенка):

https://www.diffchecker.com/XskfB9y3

Покажите свой код javascript для добавления / удаления форм.

art 02.05.2018 10:16

Сделанный. Также я проверил HTML с инспектором, который обновляет значение TOTAL_FORMS.

DavidMM 02.05.2018 10:42

Похоже, я не получаю контекстные данные формы. Проверьте раздел «обновить» в конце исходного сообщения.

DavidMM 02.05.2018 11:50

Почему у вас два Child внутри inlineformset_factory()?

art 02.05.2018 12:27

упс, это была ошибка, когда я менял оригинальные названия моделей. Это должен быть Родитель, Ребенок.

DavidMM 02.05.2018 12:34

Что bala_form в шаблоне? Вы установили prefix, как сказано (ниже) с помощью Дэниел Розман?

art 02.05.2018 12:37
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
170
1

Ответы 1

Ваш Javascript должен изменить значение поля form-TOTAL_FORMS в форме управления. См. документация по формам.

Я отредактировал исходное сообщение, добавив соответствующий раздел кода JS, а также проверил, что обновляет значение TOTAL_FORMS.

DavidMM 02.05.2018 10:39

Вы уверены, что это поле называется child-TOTAL_FORMS? Я не вижу ничего, что устанавливает префикс набора форм как «дочерний».

Daniel Roseman 02.05.2018 10:42

Да, как я уже сказал, я проверил HTML с помощью инспектора Chrome. Похоже, я неправильно получаю значения из формы, см. Обновление в OP для получения дополнительной информации.

DavidMM 02.05.2018 11:44

Другие вопросы по теме