Django formset无效

时间:2017-01-26 11:58:37

标签: django forms validation pdf error-handling

我有一个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>

1 个答案:

答案 0 :(得分:1)

您尚未将任何POST数据传递给DrawingUploadFormset。