管理表单数据丢失或已被篡改验证表单

时间:2017-01-16 17:05:01

标签: ajax django django-forms django-templates django-views

我到处搜索但我无法解决它。我的页面中有一个formset(底部的表格)。当我使用ajax按下保存按钮时,需要保存主窗体和formset。 POST请求已发送但有错误。

错误“POST / new / HTTP / 1.1”500 59

ValidationError:[u'ManagementForm数据丢失或被篡改']

Views.py

def master_detail_new(request):
    if request.method == 'GET':
    author = TmpPlInvoice()
    author_form = TmpForm(instance=author)
    BookFormSet = inlineformset_factory(TmpPlInvoice, TmpPlInvoicedet,
                                        exclude=('emp_id', 'voucher', 'lineitem', 'id',),
                                        form=TmpFormDetForm, )
    formset = BookFormSet(instance=author)
    return render(request, 'main.html',
                  {'form': author_form, 'formset': formset, 'formtotal': totalform, 'postform': postform},
                  )

    elif request.method == 'POST':
    def get_new_voucher_id():
        temp_vid = TmpPlInvoice.objects.order_by().values_list("voucher_id", flat=True).distinct()
        if not temp_vid:
            voucher_id = str(1).zfill(4)
        else:
            voucher_id = str(int(max(temp_vid)) + 1).zfill(4)
        return voucher_id

    author_form = TmpForm()
    author = TmpPlInvoice()
    BookFormSet = inlineformset_factory(TmpPlInvoice, TmpPlInvoicedet, exclude=('emp_id', 'voucher', 'lineitem', 'id',),
                                        form=TmpFormDetForm, extra=2)
    formset = BookFormSet(instance=author)
    voucher_id = get_new_voucher_id()
    author = TmpForm(request.POST)
    if author.is_valid():
        created_author = author.save(commit=False)
        created_author.voucher_id = voucher_id
        created_author.save()

        formset = BookFormSet(request.POST, instance=created_author)
        if formset.is_valid():
            formset.save()
        return HttpResponseRedirect('/')

HTML

 <div class="x_content">
    {{ formset.management_form }}
    {{ formset.non_form_errors.as_ul }}
     <table class="table table-striped responsive-utilities jambo_table   bulk_action form"
   id="formset" style="background-color:#d0ffff;">
       <thead style="background-color:#9df0e0;;color: #73879C">
{% for form in formset.forms %}
    {% if forloop.first %}
    <thead>
    <tr class="headings">
        {% for field in form.visible_fields %}
        <th>{{ field.label|capfirst }}</th>
        {% endfor %}
    </tr>
    </thead>
    {% endif %}

Javascript发送数据

$("#save").click(function() {
    $.ajax({
      type:'POST',
        url:'/new/',
        data:{
            csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
        },
        success:searchSuccess,
        dataType: 'html'
    });
   });

function searchSuccess(data, textStatus, jqXHR)
  {
    $('#myForm').html(data);
   }

我做错了什么?任何帮助将不胜感激。 Multiple formsets

修改 我没有改变表格集的数量。我的CSRF工作正常。另外,我在没有ajax的情况下遇到同样的问题。

 <input id="id_tmpplinvoicedet_set-TOTAL_FORMS" name="tmpplinvoicedet_set-TOTAL_FORMS" type="hidden" value="3" />
 <input id="id_tmpplinvoicedet_set-INITIAL_FORMS" name="tmpplinvoicedet_set-INITIAL_FORMS" type="hidden" value="0" />
 <input id="id_tmpplinvoicedet_set-MIN_NUM_FORMS" name="tmpplinvoicedet_set-MIN_NUM_FORMS" type="hidden" value="0" />
 <input id="id_tmpplinvoicedet_set-MAX_NUM_FORMS" name="tmpplinvoicedet_set-MAX_NUM_FORMS" type="hidden" value="1000" />

2 个答案:

答案 0 :(得分:2)

如果表单数量在发送到浏览器后发生了变化,则表单会引发此确切错误。 formset使用form-TOTAL_FORMSmanagement_form名称的隐藏输入字段来跟踪该数字。来自docs

  

它用于跟踪正在显示的表单实例的数量。如果您要通过JavaScript添加新表单,则还应增加此表单中的计数字段。

答案 1 :(得分:0)

这是我更改每种形式的TOTAL_FORMS的方式。注意*在将表单动态添加到页面时,我以单一表单的形式传递所有HTML和正则表达式的ID。

我叫一个添加表单按钮:

addForm: function () {
    this.count++
    let form_count = this.count
    form_count++

    let formID = 'id_form-' + this.count

    incremented_form = this.vue_form.replace(/form-\d/g, 'form-' + this.count)
    this.formList.push(incremented_form)
    this.$nextTick(() => {
        let total_forms = document.getElementsByName('form-TOTAL_FORMS').forEach
        (function (ele, idx) {
            ele.value = form_count
            })
        })
},

这将是1到全​​部TOTAL_FORMS。根据我很少的经验,django会查看最后一张表格,以查看该表格是否提交了正确的表格数量。因此,您可能不必更新