使用多个表单保存动态表单集

Saving dynamic formset with more than one form

我已经使用 django 表单集和 javascript 构建了动态表单,但不幸的是在提交表单时只提交了第一个表单。我还希望提交所有动态添加的表单。任何帮助,将不胜感激。 观看次数:

def routestepinfo(request):
    class RequiredFormSet(BaseFormSet):
            def __init__(self, *args, **kwargs):
                super(RequiredFormSet, self).__init__(*args, **kwargs)
                for form in self.forms:
                    form.empty_permitted = False    
    RouteStepFormSet = formset_factory(RouteStepForm, formset=RequiredFormSet, extra=1, can_order=False, can_delete=True)   
    if request.method == 'POST':
        formset = RouteStepFormSet(request.POST)
        if formset.is_valid():
            for form in formset.forms:
                form.save()
                print 'apple'
                return redirect("/buildpage/")
    else: 
        formset = RouteStepFormSet()
    return render(request, "buildpage/routestepinfo.html", {'formset' :formset})

HTML

<form id= "myForm" method = 'POST' action="{% url 'buildpage:routestepinfo' %}" enctype="multipart/form-data">{% csrf_token %}
                  {{ formset.management_form }}
<div id="form_set">    
                  {% for form in formset %}  
                  <table class='no_error'>
                  <tbody>.
                  {{form.as_table}}
                  </tbody>
                  </table>
                  {% endfor %}
</div>
<p><input type = "button" value = "Add another step" id = "add_more" ></p>
<div id="empty_form" style="display:none">
    <table class='no_error'>
        {{ formset.empty_form.as_table }}
    </table>
</div>
                 <div id="forms"></div>
    <p>&nbsp;</p>
    <p>&nbsp;</p>
              <input type = "submit" name = "Submit Steps">
                  </form>

JS 克隆:

<script>
    $('#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);
    });
</script>

已修复!只用了一个星期。这是它最终的工作方式。视图大部分未修改,只是添加了 commit=False 以保存列表。

def routestepinfo(request, slug=None):
    RouteStepFormSet = formset_factory(RouteStepForm, formset = RequiredFormSet, extra=1)
    if request.method == 'POST':
        formset = RouteStepFormSet(request.POST)
        print formset
        if formset.is_valid():
            for form in formset.forms:
                form_item = form.save(commit=False)
                print form
                form_item.save()
                messages.success(request, "Record created")
            return redirect ("/buildpage/")
    else: 
        formset = RouteStepFormSet()
    return render(request, "buildpage/routestepinfo.html",{'formset':formset})

Javascript 是改变的主要内容,添加了很多内容并提供了很多 SO 帮助。前缀是第一个问题,通过使用 formset.empty_form 并从那里修改它来解决。另一个重要部分是更新总表,这解决了保存问题。

<script>
$(document).ready(function() {
    $('.add-item').click(function(ev) {
        ev.preventDefault();
        var count = $('#items-form-container').children().length;
        var tmplMarkup = $('#item-template').html();
        var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count);
        $('div#items-form-container').append(compiledTmpl);

        // update form count
        $('#id_form-TOTAL_FORMS').attr('value', count+1);
        $('html, body').animate({
                scrollTop: $("#add-item-button").position().top-200
            }, 800);
    });
});
</script>

终于html了。这结合了我自己的一些东西和一个非常有用的 SO post(忘记了它来自的问题),其中 formset 生成为空表单并从那里克隆。:

        <div type="text/html" id="item-template">
          <table>
              {{ formset.empty_form.as_table }}
          </table>
          </div>
          <font face = Flexo>
          <form id= "myForm" method = 'POST' action="{% url 'buildpage:routestepinfo' %}" enctype="multipart/form-data">{% csrf_token %}
          {{ formset.management_form }}
          <div id="items-form-container">

          {% for form in formset.forms %}

          <div id="item-{{ forloop.counter0 }}">
          <table>
          {{form.as_table}}
          <table>
          </div>
          {% endfor %}
          </div>
          <a href="#" id="add-item-button" class="btn btn-info add-item">Add Step</a>
        <input type = "submit" name = "Submit Steps">
          </form>

希望这对某些人有所帮助。干杯