2016-03-29 3 views
0

Я изменяю FormSet, используя JavaScript/jQuery, динамически добавляя форму в Django FormSet. Например, я начинаю с одной формы, спрашивая о образовании Пользователя. Затем пользователь может нажать кнопку добавления, чтобы добавить идентичную форму для ввода информации о среднем образовании (например, школа градиента). Форма добавляется в браузер, и я могу вводить данные, но когда я отправляю данные, она отображает только одну форму в FormSet с информацией из второй формы в браузере.Динамически добавленные данные Django FormSet не публикуются

POST DATA

edu-0-degree u'Doctorate' 
first_name u'User' 
last_name u'One' 
Submit u'Submit' 
edu-0-date_started u'01/01/12' 
edu-MIN_NUM_FORMS u'0' 
edu-0-school u'School Two' 
edu-INITIAL_FORMS u'0' 
edu-MAX_NUM_FORMS u'1000' 
edu-0-date_finished u'01/01/16' 
edu-0-id u'' 
edu-TOTAL_FORMS u'2' 
csrfmiddlewaretoken u'qgD2supjYURWoKArWOmkiVRoBPF6Shw0' 

Я тогда получаю сообщение об ошибке сказав:

ValidationError: [u'ManagementForm data is missing or has been tampered with'].

Вот соответствующие фрагменты кода: (. Здесь я попытался с и без form.has_changed() кусок с тем же результатом)

views.py

def build_profile(request): 
    EducationFormset = modelformset_factory(EducationModel, AddEducationForm, extra=1) 

    if request.method == "POST": 

     education_formset = EducationFormset(request.POST, prefix='edu') 
     for form in education_formset: 
      if form.is_valid() and form.has_changed(): 
       education = EducationModel(
        school = form.cleaned_data['school'], 
        date_started = form.cleaned_data['date_started'], 
        date_finished = form.cleaned_data['date_finished'], 
        degree = form.cleaned_data['degree'], 
        user = current_user 
       ) 
       education.save() 

     return HttpResponseRedirect(reverse('private', args=[current_user.username])) 

    context = { 
     'edu_formset' : forms['education'], 
    } 

    return render(request, "build_profile.html", context) 

Template build_profile.html

<h2>Education</h2> 
{{ edu_formset.management_form }} 
{% for form in edu_formset.forms %} 
    <div id="{{ form.prefix }}-row" class="dynamic-form"> 
     {{ form|crispy }} 
     <div {% if forloop.first %} class="hidden" {% endif %}> 
      <button type="button" class="btn btn-default btn-sm delete-row"> 
       <span class="glyphicon glyphicon-minus" aria-hidden="true"></span> 
      </button> 
     </div> 
    </div> 
{% endfor %} 
<div class="btn-group btn-group-xs" role="group" aria-label="..."> 
    <button type="button" class="btn btn-default add-row"> 
     <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> 
    </button> 
</div> 

build_profile.js (код динамически добавлять формы к FormSet)

function updateElementIndex(el, prefix, ndx) { 

    var id_regex = new RegExp('(' + prefix + '-\\d+)'); 
    var replacement = prefix + '-' + ndx; 
    if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement)); 
    if (el.id) el.id = el.id.replace(id_regex, replacement); 
    if (el.name) el.name = el.name.replace(id_regex, replacement); 

} 

function addForm(btn, prefix) { 

    var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val()); 
    var row = $('.dynamic-form:first').clone(true).get(0); 
    $(row).removeAttr('id').insertAfter($('.dynamic-form:last')).children('.hidden').removeClass('hidden'); 
    $(row).children().not(':last').children().each(function() { 
     updateElementIndex(this, prefix, formCount); 
     $(this).val(''); 
    }); 
    $(row).find('.delete-row').click(function() { 
     deleteForm(this, prefix); 
    }); 
    $('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1); 
    return false; 

} 

function deleteForm(btn, prefix) { 

    $(btn).parents('.dynamic-form').remove(); 
    var forms = $('.dynamic-form'); 
    $('#id_' + prefix + '-TOTAL_FORMS').val(forms.length); 
    for (var i=0, formCount=forms.length; i<formCount; i++) { 
    $(forms.get(i)).children().not(':last').children().each(function() { 
     updateElementIndex(this, prefix, i); 
    }); 
} 
return false; 

} 

$(document).ready(function() { 

    $('.add-row').click(function() { 
     return addForm(this, 'edu') 
    }); 

    $('.delete-row').click(function() { 
     return deleteForm(this, 'edu') 
    }); 

}); 

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

+0

У меня есть пара вопросов. 1. В вашем html для вашей формы есть значения для полей в вашем 0-индексном наборе форм. Откуда они? 2. Имеются ли поля управления_формы в ваших данных? Не могли бы вы показать нам, как выглядят ваши данные? 3. Получаете ли вы ошибку в любое время, когда пытаетесь опубликовать ее, или это только если вы добавили форму? –

+0

@RobVezina: Я отредактировал свой вопрос, чтобы включить мои данные для публикации, а не заявление о печати, которое я включил ранее. В браузере было две формы, которые оба были заполнены, но только один, похоже, появляется в данных сообщения. Я получаю сообщение об ошибке в любое время, когда пытаюсь опубликовать сообщение, вне зависимости от того, добавила ли я форму. – eswens13

ответ

0

Вы получаете ValidationError, потому что edu_TOTAL-FORMS = 2, и только 1 форма из набора форм находится в ваших post args. Просмотрите исходный код в браузере и убедитесь, что имена ваших форм имеют префикс правильно. Похоже, что обе формы имеют префикс edu-0, и когда вы отправляете только последний в форме, публикуется.

+0

Спасибо за ваш ответ. Возникла проблема с назначением префиксов. Я думаю, что я изменил это сейчас, так что, когда добавляется вторая форма, префикс теперь «edu-1» вместо «edu-0». Однако, когда я отправляю сообщение, единственное, что приходит с префиксом «edu-1», это переменная «edu-1-id». Кроме того, данные post с префиксом 'edu-0' поступают из второй формы в браузере, а не из первой. Моя 'edu-TOTAL-FORMS' - 2 (я уверен, что это должно быть, так как я пытаюсь представить две формы). Я все равно получаю такое же сообщение об ошибке. , , – eswens13

+0

Я бы начал с удаления javascript со страницы. Получите эту работу с несколькими формами в вашем наборе форм. Только когда вы уверены, что он работает без javascript, вы должны добавить функциональность javascript и начать отладку этой части. –

+0

Да, вы, вероятно, правы. Я дам этот выстрел и посмотрю, что происходит. – eswens13

 Смежные вопросы

  • Нет связанных вопросов^_^