使用 formset / managment_form 变量时,提交的 Django 表单没有 POST 数据

Posted

技术标签:

【中文标题】使用 formset / managment_form 变量时,提交的 Django 表单没有 POST 数据【英文标题】:Submitted Django Form has no POST data when using formset / managment_form variable使用 formset / managment_form 变量时,提交的 Django 表单没有 POST 数据 【发布时间】:2012-06-19 20:27:42 【问题描述】:

我正在创建一个 Web 应用程序来使用 jQuery 动态添加表单并使用 django 后端处理它们。我根据https://docs.djangoproject.com/en/dev/topics/forms/formsets/ 的文档在 django 中使用了表单集,并尝试在http://stellarchariot.com/blog/2011/02/dynamically-add-form-to-formset-using-javascript-and-django/ 和Dynamically adding a form to a Django formset with Ajax 的*** 上遵循示例。

我遇到的问题是,当我提交表单时,我没有收到任何 POST 数据。当我删除变量 formset.management_form 时,我将数据发送到 POST 但收到错误 [u'ManagementForm 数据丢失或已被篡改']。如果我将管理表单放入模板中(我应该这样做),我不会得到任何 POST 数据。有谁知道这个的解决方案吗?

forms.py
from django import forms
from busker.models import *
from django.forms import ModelForm



class UploadFileForm(ModelForm):
   class Meta:
      model = UploadFile

class Category(models.Model):
    category = models.CharField(max_length = 50)


    def __unicode__(self):
        return self.name

models.py

from django.db import models

class UploadFile(models.Model):
    title = models.CharField(max_length = 50)
    file  = models.FileField(upload_to = 'test')

    def __unicode__(self):
        return self.name

class CategoryForm(ModelForm):
   class Meta:
      model = Category

views.py

def submit(request,action=''):

    if request.user.is_authenticated():
        class RequiredFormSet(BaseFormSet):
            def __init__(self, *args, **kwargs):
                super(RequiredFormSet, self).__init__(*args, **kwargs)
                for form in self.forms:
                    form.empty_permitted = False
        UploadFileFormSet = formset_factory(UploadFileForm,extra=2, max_num=10, formset=RequiredFormSet)

        if request.method == 'POST':    
            uploadfile_formset = UploadFileFormSet(request.POST, request.FILES,prefix='songs')
            category_form= CategoryForm(request.POST,prefix = 'category')



            if uploadfile_formset.is_valid and category_form.is_valid:
                return HttpResponseRedirect('/') #going to the home root
            else:
                return HttpResponseRedirect('/contact') #testing to see if it fails
        else:
            uploadfile_formset = UploadFileFormSet(prefix = 'songs')
            category_form= CategoryForm(prefix = 'category') 

            t = loader.get_template('submit.html')
            c = RequestContext(request, 
                 'uploadfile_formset': uploadfile_formset,
                 'category_form': category_form,
                'head_title':  u'Submit Song',
                'page_title': 'Submit Song',
                )

            return HttpResponse(t.render(c))

模板(submit.html)

<form id="songform" name="songform" enctype="multipart/form-data" action="" method="POST">% csrf_token %
     uploadfile_formset.management_form
     <div id="songforminputs">
    category_form.as_p
     % for formset in uploadfile_formset %
         <div id="dynamicInput">
         <p class = "songSubmitForm" > Song forloop.counter </p>   
         % for field in formset %
             <label class="submitForm" for="title"> field.label </label>
             field|add_class:"submitForm" 
              </br>
         % endfor %
         </div>
       % endfor %

       </div>

   <input type="button" value="Add another text input" onClick="addInput('dynamicInput');">
   <input type="button" value="Remove a text input" onClick="removeInput('dynamicInput');">
   <input type="submit" name="submitbutton" id="submitbutton" value="" >

</form>

jQuery / javascript 部分

<script type="text/javascript">
var counter = 2;
var minimum = 2;
var limit = 5;

function addInput(divName)
     if (counter == limit)  
          alert("You have reached the limit of adding " + counter + " inputs");
     
     else 

          var newdiv = document.createElement('div');
          newdiv.id = "dynamicInput";
          newdiv.innerHTML = "<p class = 'songSubmitForm' > Song " + (counter+1) +"</p>"  + "<label for='title' class='submitForm' >Title</label>" + "<input id ='id_form-" + (counter)+ "-title'type='text' class='contact' name='form-" + counter +"-title'>" + "</br>" + "<label for='file' class='submitForm' >File</label>" + " <input id='id_form-"+counter+"-file' type='file' class='contact' name='form-"+counter+"-file'>" + "</br>" + "</br>";
          document.getElementById('songforminputs').appendChild(newdiv);
          counter++;
     


function removeInput(divName)
     if (counter == minimum)  
          alert("You need at least " + counter + " inputs");
     
     else 
         $('div#dynamicInput:last-child').remove()
          counter--;
     


</script>

【问题讨论】:

你怎么知道你“没有得到任何 POST 数据”。您对 POST 的操作只是“通过”。将真实代码放在那里会发生什么? 所以问题出在我从原始代码中删除的另一段代码上。基本上我有两个与视图相关的模型/表单。当我将 request.POST 分配给每个模型时,没有传递 POST 数据。当我从模型中删除一个 request.POST 时,我可以让它工作。我仍然遇到无法在两个模型上获取 POST 数据的问题。 【参考方案1】:

我不认为您说您使用的是 django-crispy-forms,但是,我会在此处为遇到此错误的任何人发布此内容,谁知道,也许它也会对您有所帮助。

我最近在尝试使用多个清晰的内联表单集时遇到了一个非常相似的问题。我在使用% cirspy formset.form formset.form.helper % 之前添加了 formset.management_form

掌心

当我包含管理表格时,表格中的任何数据都不会在帖子中提供。当我没有包含管理表单时,django 向[u'ManagementForm data is missing or has been tampered with'] 抱怨。

要解决这个问题,只需按照设计的方式使用清晰的表单:% crispy formset formset.form.helper %。这样就不需要在它自己的标签中包含管理表单,这似乎让 Django 感到困惑。

【讨论】:

以上是关于使用 formset / managment_form 变量时,提交的 Django 表单没有 POST 数据的主要内容,如果未能解决你的问题,请参考以下文章

Django CBV - Formsets:'NoneType'对象没有属性'id'

angular.js 中的 Django formset 等效项

第77篇 formset的使用示例

Django 和 jQuery.formset,如何操作删除按钮位置

使用 formset / managment_form 变量时,提交的 Django 表单没有 POST 数据

Django formsets没有发布数据