Django:使用Jquery的动态formset只保存第一个formset实例

时间:2016-11-21 17:17:34

标签: jquery python django django-forms

所以我为样本设置了以下代码,然后是其外键的内联formset,样本细节。我还为它添加了一些动态功能,以便您可以通过Jquery为formset添加更多行。我从http://stackoverflow.com/questions/501719/dynamically-adding-a-form-to-a-django-formset-with-ajax获得了Jquery部分。我尝试了两种实现,但似乎有相同的结果。我想知道我是否在视图中做错了什么。

views.py

def project_detail (request, project_id):
     project = Project.objects.get(id = project_id)
     sample_form = SampleForm(request.POST or None, request.FILES or None, instance = project)
     SampleInlineFormSet = inlineformset_factory(Sample, SampleDetail, form=SampleDetailForm, extra=1, can_delete = False)
     formset = SampleInlineFormSet(request.POST or None, request.FILES or None, prefix="nested")
     if request.method == "POST":

        if 'sampleform' in request.POST:
            if sample_form.is_valid() and formset.is_valid():
                 sample_temp = sample_form.save()
                 sample = Sample.objects.get(pk = sample_temp.pk)
                 objects = formset.save(commit=False)
                 for object in objects:
                       object.sample = sample
                       object.save()

                 messages.success(request, "Sucessfully Created New Sample Log" )
                 return HttpResponseRedirect(reverse('projstatus:project_detail', args=(project_id,)))           
     context = {'project' : project, "sample_form":sample_form, 'formset' : formset}
     return render(request, 'projstatus/detail.html', context)   

forms.py

<form method='POST' action='' enctype='multipart/form-data'>{% csrf_token %}
             {% crispy sample_form %}

             <div id="form_set">
                 {{ formset.management_form }}
                 {% for form in formset.forms %}
                     <table class='no_error'>

                         {{ form.as_table }}
                     </table>
                 {% endfor %}
             </div>
             <input type="button" value="Add More" id="add_more">

             <div id="empty_form" style="display:none">
                 <table class='no_error'>
                     {{ formset.empty_form.as_table }}

                 </table>
             </div>
             <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>


              <button type='submit' class='save btn btn-default' name = 'sampleform'>Save</button>      

             </form>

但是,我遇到这个问题,只保存了第一个formset实例。不管我动态放了多少。有人可以帮助我吗?

编辑:

表格的外观 enter image description here

使用Jquery添加一个实例时的POST数据(总共2个实例) enter image description here

不使用Jquery时POST数据,设置extra = 2.(总共2个实例) enter image description here

2 个答案:

答案 0 :(得分:3)

我认为您的问题与您的javascript有关。看来你从另一个漂浮的例子中拿走了这个片段。

var form_idx = $('#id_form-TOTAL_FORMS').val();

要实现这一目标,需要有id id_form-TOTAL_FORMS的元素。

但我认为你的表单可能会输入id为id_nested-TOTAL_FORMS之类的东西或类似东西。因此,我认为您的javascript实际上并未更新Formset的管理表单数据。

您应该检查页面上的html,看看此输入的id是什么。另外,使用javascript控制台查看您的JS代码实际上在做什么。

答案 1 :(得分:1)

与上一个答案一样,每次添加一个时,nested-TOTAL_FORMS字段值都需要使用行数进行更新。您目前正在更新不存在的字段form-TOTAL_FORMS

尝试将js从#id_form-TOTAL_FORMS更新为#id_nested-TOTAL_FORMS

可能还有一种方法可以将字段ID作为模板变量,但目前让我不知所措。

相关问题