【问题标题】:Django formset is not valid- why not?Django formset 无效- 为什么不呢?
【发布时间】:2017-06-09 10:30:01
【问题描述】:

我正在尝试使用一种表单来允许用户将图像上传到存储在我的 Django 项目中的数据库中的项目,但是,我目前正在获取控制台输出,告诉我我正在使用的 formset 不是有效...

我试图用来将图像上传到项目的视图已定义为:

def upload_budget_pdfs(request, project_id):
    project = Project.objects.get(id=project_id)
    print("Value of project in 'upload_budget_pdfs()': ", project)

    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():
        print 'Saving drawing_formset'
        print "Before", [b.id for b in project.budget_versions.all()]
        for drawing_form in drawing_formset:
            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]))

调用此视图时我得到的控制台输出是:

("'upload_budget_pdfs()'中项目的价值:", )

("'upload_budget_pdfs()' 中演示文稿的值:",[,,, , , , , , , , , , , , , , , , , , '...(剩余元素被截断)...'])

("'upload_budget_pdfs()'中的drawing_formset的值:", )

绘图表单集无效。 []

所以很明显,我认为else 语句是这里正在运行的,但我不确定为什么,因为控制台清楚地表明变量都包含正确的数据......

我在这里初始化drawing_formset 变量的方式有什么问题?我传递给DrawingUploadFormset(...)queryset 是否正确? is_valid() 实际检查了什么?

编辑

我对接受的答案进行了更改,因此我的 drawing_formset 声明现在是:

        drawing_formset = DrawingUploadFormset(request.POST, request.FILES, prefix="drawings", queryset=Drawing.objects.filter(budget__in=presentations).order_by('budget__presentation_date', 'budget__created'))

但我现在似乎收到“内部服务器错误”和MultiValueDictKeyError 在线:

for drawing_form in drawing_formset: #This line is what's causing the MultiValueDictKeyError

我不明白这是为什么?有什么建议吗?

【问题讨论】:

    标签: django formset


    【解决方案1】:

    您的表单集不包含任何数据。您需要传递 request.POSTrequest.FILES 作为第一个和第二个参数(或作为 datafiles 关键字参数),但前提是它是实际的表单提交。

    如果没有数据传入表单或表单集,则视为未绑定,将返回False 而不检查错误。

    通常的模式是在request.method == 'POST'时传递它们,然后验证formset:

    def upload_budget_pdfs(request, project_id):
        ...
        if request.method == 'POST':
            drawing_formset = DrawingUploadFormset(request.POST, request.FILES, prefix='drawings', queryset=...)
            if drawing_formset.is_valid():
                # save formset
                return HttpResponseRedirect(...)
        else:
            drawing_formset = DrawingUploadFormset(prefix='drawings', queryset=...)
        return render(...)  # Render formset
    

    这将在 GET 上显示一个空白表单,在提交失败时显示一个带有错误消息的填写表单,并且它将保存表单集并在成功提交时重定向。

    【讨论】:

    • 啊,好的,我认为这是有道理的,谢谢。那么我会在view 中这样做吗,就像您在回答中所做的那样?表单上有一个“提交”按钮,它应该处理实际的表单提交-但这不是由 view...
    • 如果提交来自不同的视图,您可以省略 else: 分支。但是,您需要决定当表单集无效时该怎么做。要么你需要重定向回来(在这种情况下你会丢失提交的数据),要么你需要在这个视图中呈现表单。
    • 好的,谢谢。所以我试了一下,我认为它让我朝着正确的方向前进,但是当我点击“提交”按钮提交表单时,我又遇到了另一个错误,已经上传了一个 PDF 文件......错误是AttributeError 并说:'WSGIRequest' object has no attribute 'Files'...知道这是为什么吗?
    • 应该是request.FILES,而不是request.Files。 Python 区分大小写。
    • 啊,抱歉 - 错过了错字 - 但在排序后,当我点击“提交”按钮时,我收到了一个 MultiValueDictKeyError: "u'drawings-4-id'"...我不确定这是为什么?
    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-26
    • 1970-01-01
    相关资源
    最近更新 更多