Набор форм Django: сохранение нескольких форм из набора форм - PullRequest
0 голосов
/ 12 ноября 2018

Я потратил несколько дней, чтобы add dynamically forms to formset, и я нашел способ сделать это.Но у меня есть небольшая проблема с forms saving, потому что она просто сохраняет первую форму, а не все формы из набора форм.

Это мой набор форм:

DocumentFormSets = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1, max_num=4)

Это мой шаблон:

<fieldset>
    <legend class="title"><span class="name">{% trans 'Document form' %}</span></legend>
    {{ DocumentFormSet.management_form }}
    <div id="form_set">
      {% for form in DocumentFormSet.forms %}
        <div class='formset-document'>
          <table class='no_error'>
            <div class="row">
              <div class="col-xs-3">
                {{ form.title|as_crispy_field }}
              </div>
              <div class="col-xs-3">
                {{ form.language|as_crispy_field }}
              </div>
              <div class="col-xs-3">
                {{ form.format|as_crispy_field }}
              </div>
              <div class="col-xs-3">
                {{ form.upload|as_crispy_field }}
              </div>
            </div>
          </table>
        </div>
      {% endfor %}
    </div>
    <br>
    <input type="button" class="btn btn-default" value="Add More" id="add_more">
    <div id="empty_form" style="display:none">
      <table class='no_error'>
        <div class="row">
          <div class="col-xs-3">
            {{ DocumentFormSet.empty_form.title|as_crispy_field }}
          </div>
          <div class="col-xs-3">
            {{ DocumentFormSet.empty_form.language|as_crispy_field }}
          </div>
          <div class="col-xs-3">
            {{ DocumentFormSet.empty_form.format|as_crispy_field }}
          </div>
          <div class="col-xs-3">
            {{ DocumentFormSet.empty_form.upload|as_crispy_field }}
          </div>
        </div>
      </table>
    </div>
</fieldset>

Это моя часть JS:

$('#add_more').click(function () {
  var form_idx = $('#id_form-TOTAL_FORMS').val();
  $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
  $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
});

А это мой файл views.py:

class PublicationCreateView(EdqmCreateView):
    """ Create publication with document form through formset """
    model = Publication
    template_name = 'freepub/publication/publication_form.html'

    def get_context_data(self, **kwargs):
        context = super(PublicationCreateView, self).get_context_data(**kwargs)
        context['DocumentFormSets'] = DocumentFormSets(self.request.POST or None, self.request.FILES or None)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formsets = context['DocumentFormSets']
        if form.is_valid() and formsets.is_valid():
            self.object = form.save()
            formsets.instance = self.object
            formsets.save()
        return super(PublicationCreateView, self).form_valid(form)

Но с помощью этой функции он сохраняет толькоПервая форма документа в моем наборе форм:

Я просмотрел поле формы документа id и получил:

enter image description here

Первое поле заголовкаполучить id_documents-0-title, но когда я добавляю больше форм, поле заголовка становится всегда id_documents-undefined-title

Как сохранить формы документов из наборов форм?

Спасибо!

РЕДАКТИРОВАТЬ:

Это изменение от @HaiLang вопрос:

Это мой self.request.POST:

<QueryDict: {'csrfmiddlewaretoken': ['0LHaaEG1dkyZmOnP3X7037tZI45QrQOIRrQQAMhiOoTyeohDwQdcdTt08yuqH86Z'], 'category': ['23'], 'pub_id': ['PUBSDDD-55'], 'title': ['TESTPUBLIE'], 'description': [''], 'doc-TOTAL_FORMS': ['1'], 'doc-INITIAL_FORMS': ['0'], 'doc-MIN_NUM_FORMS': ['0'], 'doc-MAX_NUM_FORMS': ['4'], 'doc-0-title': ['doc1'], 'doc-0-language': ['FR'], 'doc-0-format': ['pdf'], 'doc-undefined-title': ['doc2'], 'doc-undefined-language': ['FR'], 'doc-undefined-format': ['pdf'], 'doc-__prefix__-title': [''], 'doc-__prefix__-language': [''], 'doc-__prefix__-format': [''], 'doc-__prefix__-upload': ['']}>

И это мой console.log:

Element kt.fn.init {}

1 Ответ

0 голосов
/ 15 ноября 2018

К счастью, я недавно работал с FormSet, поэтому вижу проблему с соответствующим кодом.

(Под редакцией Даки. Спасибо!)

Вы должны установить одинаковые prefix между вашим файлом views.py и файлом app.js. Потому что в вашем файле просмотра вы используете prefix='doc', а в функции javascript вы используете form префикс.

Итак, в вашем файле JQuery вы должны написать:

(function ($) {
$('#add_more').click(function () {
    var form_idx = $('#id_doc-TOTAL_FORMS').val();
    // For debugging the issue
    // console.log('Element', $('#id_doc-TOTAL_FORMS'), 'Num of forms', form_idx);
    $('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
    $('#id_doc-TOTAL_FORMS').val(parseInt(form_idx) + 1);
    console.log('Element', $('#id_doc-TOTAL_FORMS'));
});
})(jQuery)

Вы можете переписать свой вид следующим образом:

class PublicationCreateView(CreateView):
    """ Create publication with document form through formset """
    model = Publication
    template_name = 'publication_form.html'

    def get_context_data(self, **kwargs):
        context = super(PublicationCreateView, self).get_context_data(**kwargs)
        document_queryset = Document.objects.all()
        context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None, prefix='doc', queryset=document_queryset)
        return context

    def form_valid(self, form):
        context = self.get_context_data()
        formsets = context['DocumentFormSets']
        // For debugging
        // print(self.request.POST)
        if form.is_valid() and formsets.is_valid():
            self.object = form.save()
            formsets.instance = self.object
            formsets.save()
        return super(PublicationCreateView, self).form_valid(form)
...