ManagementForm 数据缺失或被篡改
我正在尝试创建一个表单集合,以便一次性保存多个记录。但是,当我提交表单时,总是出现错误。如果可以的话,请告诉我应该如何保存这批记录。
我的 views.py 文件:
def weekly_progress(request):
ProgressFormSet = formset_factory(WeeklyProgressReportForm, extra=16)
formset = ProgressFormSet(request.POST or None)
if formset.is_valid():
for f in formset:
print(f)
return render(request, "progress/progressentry.html", {'formset' : formset})
我的 forms.py 文件:
class WeeklyProgressReportForm(forms.ModelForm):
class Meta:
model = WeeklyProgressReport
fields = ('target_date', 'this_date', 'pkgno', 'slno', 'description', 'unit', 'receipt_this_week', 'issue_this_week', 'erection_this_week')
widgets = {
'target_date': forms.DateInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
'this_date': forms.DateInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
'pkgno': forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
'slno': forms.NumberInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
'description': forms.Textarea(attrs={'class': 'form-control', 'rows': 1, 'readonly': 'readonly'}),
'unit': forms.TextInput(attrs={'class': 'form-control', 'readonly': 'readonly'}),
'receipt_this_week': forms.NumberInput(attrs={'class': 'form-control', 'step': 0.01}),
'issue_this_week': forms.NumberInput(attrs={'class': 'form-control', 'step': 0.01}),
'erection_this_week': forms.NumberInput(attrs={'class': 'form-control', 'step': 0.01, 'readonly': 'readonly'}),
}
我的模板:
<form id="contractor-form" method="post" action="">
{% csrf_token %}
<!-- First Row -->
<div class="col-lg-6">
<div class="panel panel-primary">
<div class="panel-heading">Select Your Package</div>
<div class="panel-body">
<div class="col-lg-4">
<h4><label class="label label-primary">Package Number</label></h4>
</div>
<div class="col-lg-4">
<select id="pkgno-select" class="form-control">
<option value="12 (BRP)">12 (BRP)</option>
<option value="13 (BRP)">13 (BRP)</option>
<option value="13 (DHB)">13 (DHB)</option>
<option value="14 (DHB)">14 (DHB)</option>
</select>
</div>
<div class="col-lg-4">
<button type="button" id="date-edit" class="btn btn-warning">Edit Date</button>
</div>
</div>
</div>
</div>
<!-- Second Row -->
<div class="col-lg-12">
<div class="panel panel-primary">
<div class="panel-heading">Quantities</div>
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>Target Date</th>
<th>This Date</th>
<th>Pkg Number</th>
<th>Sl Number</th>
<th>Description</th>
<th>Unit</th>
<th>Receipt This Week</th>
<th>Issue This Week</th>
<th>Erection This Week</th>
</tr>
</thead>
<tbody>
{% for form in formset %}
<tr>
<td>{{ form.target_date }}</td>
<td>{{ form.this_date }}</td>
<td>{{ form.pkgno }}</td>
<td>{{ form.slno }}</td>
<td>{{ form.description }}</td>
<td>{{ form.unit }}</td>
<td>{{ form.receipt_this_week }}</td>
<td>{{ form.issue_this_week }}</td>
<td>{{ form.erection_this_week }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Submit Button -->
<div class="well well-lg">
<button type="submit" class="btn btn-success btn-lg btn-block">Save</button>
</div>
</form>
我的 models.py 文件:
class WeeklyProgressReport(models.Model):
target_date = models.DateField()
this_date = models.DateField()
pkgno = models.CharField(max_length=10)
slno = models.IntegerField(max_length=2)
description = models.CharField(max_length=50)
unit = models.CharField(max_length=5)
target_quantity = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
receipt_previous = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
receipt_this_week = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
issue_previous = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
issue_this_week = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
erection_previous = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
erection_this_week = models.DecimalField(max_digits=12, decimal_places=2, blank=True, default=0)
def __unicode__(self):
return self.pkgno
4 个回答
0
对于那些在模板中确实有 {{ formset.management_form }}
,并且使用了正确的表单集变量名,但仍然看到错误信息的人
ManagementForm data is missing or has been tampered with
确保不要用空的 data
来初始化你的表单集
比如说,data=None
这样是没问题的:
>>> MyFormSet(data=None).non_form_errors()
[]
但是,data={}
这样就会出问题:
>>> MyFormSet(data={}).non_form_errors()
['ManagementForm data is missing or has been tampered with. Missing fields: ...']
注意
如果你在处理 GET
请求时尝试使用 MyFormSet(data=request.POST)
,也会出现后面提到的情况,因为这时 request.POST
会是一个空的 QueryDict
。
如果需要,可以用其他方法解决,比如 MyFormSet(data=request.POST or None)
。
4
我之前也遇到过同样的问题,就是在同一页面上使用两个表单组(formset)。我把解决办法分享出来,因为我在其他地方没找到。
确保你在请求中添加 prefix
参数,像这样:
formset = ProgressFormSet(request.POST or None, prefix="fs1")
这个参数要在 GET 和 POST 请求中都加上。
12
在你的 {% for form in formset %}
之前,写上 {{ formset.management_form }}
像这样
{{ formset.management_form }}
{% for form in formset %}
45
你需要在你的模板中渲染管理表单。文档里解释了为什么要这样做以及怎么做;这里有一些选摘的内容:
这个表单是用来帮助管理表单集合的。如果你不提供这些管理数据,就会出现错误[.]
管理表单可以通过表单集合本身来获取。当你在模板中渲染表单集合时,可以通过渲染
{{ my_formset.management_form }}
来包含所有的管理数据(记得把你的表单集合名称替换成合适的)。