我有一个Django网站,在其中一个页面上有一个表单,用户可以使用该表单输入有关特定项目的演示文稿的详细信息。一个项目可以有多个演示文稿(每个演示文稿都针对该项目的单个预算),但只有一个演示文稿将用于“当前”预算(即当前“已接受的”预算)。
可以为每个演示文稿上传预算的“PDF包”功能 - 通过单击表单上的“选择文件”按钮,使用打开的对话框选择要上载的PDF,然后单击表单上的“上传”按钮。完成后,“PDF”图标将显示在显示“选择文件”按钮的位置,单击此图标将在浏览器中打开一个新选项卡,其中将显示PDF文件的预览。
我现在正在尝试向表单添加第二个按钮,以允许用户将“绘图”文件(可能也是PDF文件)上传到表单。
我在表单上放置了“选择文件”按钮,然后单击它会打开一个对话框,允许用户选择该文件。一旦他们选择了文件,文件就会显示在按钮旁边,因此文件已添加到表单中,准备好在用户单击“上传”按钮时上传到数据库。
点击“上传”按钮后,表格中输入的所有信息(包括PDF文件和图纸文件)都应添加到数据库中的项目预算中。
然而,尽管这个“上传”按钮在上传原始PDF包文件时仍然有效,但由于我已将“图纸”文件添加到表单中,因此它似乎已经打破。如果我点击“上传”只有一个附加到表单的PDF,它可以工作,但如果我在表单上附加一个“绘图”文件时单击“上传”,则文件不会上传,我的控制台会显示一些输出话说:
('绘制formset无效。',[])
我知道这个输出来自用于上传PDF包和绘图到表单的视图(这是我添加到view
的一些错误处理的输出,但我'我不确定为什么/导致此错误处理代码运行的原因...将PDF和图纸上传到表单的视图定义为:
def upload_budget_pdfs(request, project_id):
project = Project.objects.get(id=project_id)
print("Value of project in 'upload_budget_pdfs()': ", project)
if request.method == 'POST':
presentations = project.budget_versions.select_related('meeting').prefetch_related('budget_items', 'cci_items', 'presenters').filter(version_number__isnull=False).annotate(vn=F('version_number') * -1).order_by('presentation_date', 'created', '-vn')
print("Value of presentations in 'upload_budget_pdfs()': ", presentations)
drawing_formset = DrawingUploadFormset(prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created'))
print("Value of drawing_formset in 'upload_budget_pdfs()': ", drawing_formset)
if drawing_formset.is_valid():
#if drawing_formset != None:
print 'Saving drawing_formset'
print "Before", [b.id for b in project.budget_versions.all()]
for drawing_form in drawing_formset: #ERF(24/01/2017 @ 1610) This line is what's causing the MultiValueDictKeyError
if drawing_form.instance.budget:
print 'Instance', drawing_form.instance.budget
drawing = drawing_form.save(commit=False)
drawing.budget = drawing_form.instance.budget
drawing.save()
print drawing, [b.id for b in project.budget_versions.all()]
else:
print("Drawing formset not valid.", drawing_formset.errors)
budget_formset = BudgetPresentationFormset(request.POST, request.FILES, instance=project, prefix="presentations")
if budget_formset.is_valid() and budget_formset.has_changed():
updated_budget_presentations = budget_formset.save()
elif budget_formset.has_changed(): print 'Budget formset not valid.',budget_formset.errors
return HttpResponseRedirect(reverse('projects:concept', args=[project_id]))
因此我在控制台中收到此错误的原因是因为else
语句的if
子句:if drawing_formset.is_valid():
正在运行。
如上面view
所示,drawing_formset
定义为:
drawing_formset = DrawingUploadFormset(prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created'))
和DrawingUploadFormset
在此应用的forms.py
文件中定义,其中包含:
class DrawingUploadForm(ValidatedForm):
class Meta(object):
model = Drawing
fields = ['pdf',]
DrawingUploadFormset = modelformset_factory(Drawing, form=DrawingUploadForm, max_num=12, extra=1, can_delete=False)
我不明白为什么声明if drawing_formset.is_valid():
正在返回false
...有人可以向我解释这个吗?在我如何宣布/使用drawing_formset
时,我有什么问题吗?在评估此if
语句时似乎没有任何错误,因为print
语句只显示一个空数组[]
,其中将显示drawing_formset.errors
...但不知何故,if
语句正在评估false
......为什么会这样?
修改
好的,所以我按照建议对drawing_formset
的定义进行了编辑,现在这行:
drawing_formset = DrawingUploadFormset(request.POST.get('drawings'), request.FILES, prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created'))
我缩小了该错误似乎来自行for drawing_form in drawing_formset:
,并用try-catch
包围了这个错误,看看我是否能确切地找到问题所在。这部分代码现在看起来像这样:
try:
for drawing_form in drawing_formset: #ERF(24/01/2017 @ 1610) This line is what's causing the MultiValueDictKeyError
print 'for loop entered in upload_budget_pdfs() - line 1034 '
if drawing_form.instance.budget:
drawing = drawing_form.save(commit=False)
drawing.budget = drawing_form.instance.budget
drawing.save()
print drawing, [b.id for b in project.budget_versions.all()]
except Exception as e:
print '%s (%s)' % (e.message, type(e))
这将在控制台中显示以下输出:
ManagementForm数据丢失或已被篡改()
这是我第一次看到这样的错误消息,并且不知道它意味着什么,或者如何解决它......任何人都有任何建议吗?
修改
我将给定的答案标记为“已接受”,因为这是解决方案的一部分,并指出了寻找完整解决方案的正确方向。
如果其他人有类似的问题,我会添加它以使其完全正常工作,我需要在我的模板中包含drawing_formset
变量。
我是通过在相关的HTML标记中嵌套以下内容来完成此操作的:
<tr>
{% if not forloop.last %}
<td colspan="3"><label>Budget PDF package</label></td>
{% endif %}
<td colspan="3"><label>Drawings</label></td>
<!-- Need to include the formset in the template -->
{{ drawing_formset.as_table }}
{{ drawing_formset.management_form }}
</tr>
答案 0 :(得分:1)
您尚未将任何POST数据传递给DrawingUploadFormset。