2016-03-29 5 views
0

Ich modifiziere ein FormSet mit JavaScript/jQuery, indem ich dynamisch ein Formular zu einem Django-FormSet hinzufüge. Zum Beispiel beginne ich mit einem Formular, das nach der Ausbildung eines Benutzers fragt. Der Benutzer kann dann eine Hinzufügen-Schaltfläche drücken, um ein identisches Formular hinzuzufügen, um Informationen über die weiterführende Schule einzugeben (z. B. die Schule). Das Formular wird im Browser hinzugefügt und ich kann Daten eingeben, aber wenn ich die Daten POST, zeigt es nur ein Formular im FormSet mit den Informationen aus dem zweiten Formular im Browser.Dynamisch hinzugefügte Django-FormSet-Daten werden nicht gesendet

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' 

Ich erhalte dann eine Fehlermeldung,:

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

Hier sind die relevanten Teile des Codes: (. Hier habe ich mit und ohne form.has_changed() Stück mit dem gleichen Ergebnis versucht haben)

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) 

Vorlage 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 (Der Code dynamisch Formen der FormSet hinzufügen)

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') 
    }); 

}); 

Was mache ich falsch?

+0

Ich habe ein paar Fragen. 1. In Ihrem HTML für Ihr Formular gibt es Werte für die Felder in Ihrem 0-Index-Formularsatz. Woher kommen die? 2. Sind in den Feldern von managment_form Daten vorhanden? Können Sie uns zeigen, wie Ihre Postdaten aussehen? 3. Erhalten Sie den Fehler jedes Mal, wenn Sie versuchen, zu veröffentlichen, oder ist es nur, wenn Sie ein Formular hinzugefügt haben? –

+0

@RobVezina: Ich habe meine Frage bearbeitet, um meine Postdaten und nicht die Druckanweisung, die ich zuvor eingefügt hatte, einzuschließen. Es gab zwei Formulare im Browser, die beide ausgefüllt waren, aber nur einer scheint in den Postdaten zu erscheinen. Ich bekomme den Fehler jedes Mal, wenn ich versuche zu posten, ob ich ein Formular hinzugefügt habe oder nicht. – eswens13

Antwort

0

Sie erhalten den ValidationError, weil edu_TOTAL-FORMS = 2 und nur 1 Formular aus dem Formset in Ihren Postargs ist. Zeigen Sie die Quelle im Browser an und stellen Sie sicher, dass die Namen Ihrer Formulare korrekt vorangestellt sind. Es sieht so aus, als ob beide Formulare das Präfix edu-0 haben und wenn Sie nur das letzte Formular einreichen, wird das Formular gepostet.

+0

Vielen Dank für Ihre Antwort. Es gab ein Problem mit den zugewiesenen Präfixen. Ich denke, ich habe das jetzt geändert, so dass, wenn ein zweites Formular hinzugefügt wird, das Präfix nun 'edu-1' statt 'edu-0' ist. Wenn ich jedoch poste, ist das einzige, was mit einem Präfix von 'edu-1' durchkommt, die 'edu-1-id'-Variable. Außerdem stammen die Post-Daten mit dem Präfix 'edu-0' von der zweiten Form im Browser und nicht von der ersten. Mein 'edu-TOTAL-FORMS' ist 2 (was ich ziemlich sicher bin, da ich versuche, zwei Formulare einzureichen). Ich bekomme immer noch die gleiche Fehlermeldung. . . – eswens13

+0

Ich würde damit beginnen, das Javascript von der Seite zu entfernen. Erhalten Sie das Arbeiten mit mehreren Formularen in Ihrem Formset. Nur wenn Sie sicher sind, dass es ohne Javascript funktioniert, sollten Sie die JavaScript-Funktionalität wieder hinzufügen und das Debuggen dieses Teils starten. –

+0

Ja, du hast wahrscheinlich recht. Ich werde es versuchen und sehen, was vor sich geht. – eswens13

Verwandte Themen