Django formsets не сохраняет все формы в базу данных

  1. У меня есть набор форм для одновременного отображения нескольких форм. По умолчанию отображаются только две формы.
  2. Используя JavaScript, я добавляю еще две формы к набору форм, так что общее количество форм теперь четыре.
  3. Когда я отправил POST запрос, мое представление сохраняет в базе данных только первые два объекта. Данные из форм, добавленные с помощью JavaScript, не сохраняются.

Что я делаю неправильно? Мой код:

Это мой файл forms.py, где я определяю свой набор форм.

class AddAnswerForm(ModelForm):
    class Meta:
        model = Answer
        exclude = ['question']
        widgets = {
            'answer_text': forms.TextInput(attrs={'class': 'input'}),
        }

AnswerFormSet = modelformset_factory(Answer, form=AddAnswerForm, extra=2, max_num=4)

Это JS код, который я использую для добавления новых форм на страницу (это не мой код, но он работает).

<script>
  let answerForm = document.querySelectorAll(".answer-form")
  let container = document.querySelector("#question-form")
  let addButton = document.querySelector("#add-form")
  let totalForms = document.querySelector("#id_form-TOTAL_FORMS")

  let formNum = answerForm.length-1
  addButton.addEventListener('click', addForm)

  function addForm(e){
    e.preventDefault()

    let newForm = answerForm[0].cloneNode(true)
    let formRegex = RegExp(`form-(\\d){1}-`, 'g')

    formNum++
    newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form=${formNum}-`)
    container.insertBefore(newForm, addButton)

    totalForms.setAttribute('value', `${formNum+1}`)
  }
</script> 

Вот мое мнение.

class QuestionAddView(View):
    form_class = NewQuestionForm
    form_class_for_answers = AnswerFormSet
    template_name = 'questions/question_add.html'

    def get(self, request, *args, **kwargs):
        form = self.form_class()
        answers_form = self.form_class_for_answers(queryset=Answer.objects.none())

        return render(request, self.template_name, {'form': form, 'answers_form': answers_form})

    def post(self, request, *args, **kwargs):
        form = self.form_class(request.POST, request.FILES)
        answers_form = self.form_class_for_answers(request.POST)
        print(request.POST)
        if form.is_valid() and answers_form.is_valid():
            new_question = form.save(commit=False)
            new_question.author = request.user
            new_question.save()
            print(answers_form)

            instances = answers_form.save(commit=False)
            print(instances)
            for instance in instances:
                print(instance)
                instance.question = new_question
                instance.save()

            return HttpResponseRedirect('/')

print(request.POST) печатает:

<QueryDict: {'csrfmiddlewaretoken': ['eTaR0N4LgG1WvfK3zshqOcEMYUMvXWkxctfS6OXD9E2rMbMe5VrlTVsBgnjoM2zd'], 'title': ['321321'], 'picture': [''], 'body': ['123123'], 'difficulty': ['None'], 'answer_explanation': ['12321'], 'form-TOTAL_FORMS': ['4'], 'form-INITIAL_FORMS': ['0'], 'form-MIN_NUM_FORMS': ['0'], 'form-MAX_NUM_FORMS': ['4'], 'form-0-answer_text': ['orage'], 'form-0-id': [''], 'form-1-answer_text': ['apple'], 'form-1-id': [''], 'form=2-answer_text': ['grapes'], 'form=2-id': [''], 'form=3-answer_text': ['pear'], 'form=3-id': ['']}>

print(answers_form) выведите это. Итак, я предполагаю, что JS скрипт делает свою работу правильно

<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS"><input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS"><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS"><input type="hidden" name="form-MAX_NUM_FORMS" value="4" id="id_form-MAX_NUM_FORMS"><tr>
    <th><label for="id_form-0-answer_text">Answer text:</label></th>
    <td>
      
      <input type="text" name="form-0-answer_text" value="orage" class="input" maxlength="250" id="id_form-0-answer_text">
      
      
    </td>
  </tr>

  <tr>
    <th><label for="id_form-0-is_correct">Is correct:</label></th>
    <td>
      
      <input type="checkbox" name="form-0-is_correct" id="id_form-0-is_correct">
      
      
        <input type="hidden" name="form-0-id" id="id_form-0-id">
      
    </td>
  </tr><tr>
    <th><label for="id_form-1-answer_text">Answer text:</label></th>
    <td>
      
      <input type="text" name="form-1-answer_text" value="apple" class="input" maxlength="250" id="id_form-1-answer_text">
      
      
    </td>
  </tr>

  <tr>
    <th><label for="id_form-1-is_correct">Is correct:</label></th>
    <td>
      
      <input type="checkbox" name="form-1-is_correct" id="id_form-1-is_correct">
      
      
        <input type="hidden" name="form-1-id" id="id_form-1-id">
      
    </td>
  </tr><tr>
    <th><label for="id_form-2-answer_text">Answer text:</label></th>
    <td>
      
      <input type="text" name="form-2-answer_text" class="input" maxlength="250" id="id_form-2-answer_text">
      
      
    </td>
  </tr>

  <tr>
    <th><label for="id_form-2-is_correct">Is correct:</label></th>
    <td>
      
      <input type="checkbox" name="form-2-is_correct" id="id_form-2-is_correct">
      
      
        <input type="hidden" name="form-2-id" id="id_form-2-id">
      
    </td>
  </tr><tr>
    <th><label for="id_form-3-answer_text">Answer text:</label></th>
    <td>
      
      <input type="text" name="form-3-answer_text" class="input" maxlength="250" id="id_form-3-answer_text">
      
      
    </td>
  </tr>

  <tr>
    <th><label for="id_form-3-is_correct">Is correct:</label></th>
    <td>
      
      <input type="checkbox" name="form-3-is_correct" id="id_form-3-is_correct">
      
      
        <input type="hidden" name="form-3-id" id="id_form-3-id">
      
    </td>
  </tr>

print(instances) дает:

[<Answer: orage>, <Answer: apple>]

Итак, мой вопрос: как правильно добавить данные из форм, созданных на JS, в базу данных?

Посмотрите на данные вашего сообщения, вы отправляете form-1-answer_text для второй формы, а для третьей - form=2-answer_text со знаком равенства('=')

Вам нужно исправить свой js:

newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form-${formNum}-`)
Вернуться на верх