带有内联表单集的 Django 表单验证

Posted

技术标签:

【中文标题】带有内联表单集的 Django 表单验证【英文标题】:Django form validation with inline formsets 【发布时间】:2011-09-17 14:40:57 【问题描述】:

我在一个 html 页面上有一个主表单和三个内联 forset,目的是为客户创建 Estimates。 “主”表单的主键用作所有三个内联表单集的外键。我可以创建新的估计,保存它们,更改数据等。没问题。但是,它只有在所有必需的数据都存在并且“有效”的情况下才有效。

如何让 HTML 页面重新显示并输入所有数据,但在正确位置显示错误?

为了进一步解释我的情况,单个简单表单的正常方法是这样的(这是我的想法,所以希望我没有代码错误):

if request.method=='POST':
    myform = Model_Form(request.POST)
    if myform.is_valid():
        myform.save()
        ...
        return HttpResponseredirect(...)
else:
    myform = new form from model etc...
return render_to_respose(template.html, 'myform':myform, context_instance=RequestContext(request))

现在,根据上述情况,如果出现验证错误,表单将重新显示用户已提交的数据,并在相应字段旁边显示一些错误。

使用内联表单集,我们可以这样做(假设 myForm 有 PK 并且 myInline 通过外键使用该 PK):

if request.method=='POST':
    myform = Model_Form(request.POST)
    if myform.is_valid():
        tmp = myform.save(commit=False)
        myInline = inlineFormset(request.POST, instance=tmp)
        if myInline.is_valid():
            myInline.save()
            myform.save()
            return HttpResponseRedirect(...)
else:
    myform = new form from model etc...
    myInline = new inline formset from model etc...
return render_to_respose(template.html, 'myform':myform, 'myInline':myInline, context_instance=RequestContext(request))

所以对于上面的代码,如果我在myForm 中有验证错误,我们会退出if 语句并重新显示表单以显示错误。但是,尚未创建内联表单(myInline = inlineFormset(request.POST, instance=tmp) 行),因为该步骤发生在检查myForm 的有效性之后,我们收到错误myInline Referenced before assignment 或其他错误。

为了解决这个问题,我尝试移动线条:

        tmp = myform.save(commit=False)
        myInline = inlineFormset(request.POST, instance=tmp)

在检查 myForm 是否有效之前,我可以捕获内联表单的 POST 数据。但我不能这样做,因为我没有检查myForm 是否有效。

鸡和蛋。啊!

那么,在重新显示用户为内联表单集输入的内容时, 如何进行验证并显示表单的输入错误?

很抱歉这篇文章很长,但我不知道如何缩短问题。


编辑:

好的,我知道如何显示myForm 主表单的验证错误并重新显示所有myForm 字段以及myInline 表单集字段。它是这样的:

if request.method=='POST':
    myform = Model_Form(request.POST)
    if myform.is_valid():
        tmp = myform.save(commit=False)
        myInline = inlineFormset(request.POST, instance=tmp)
        if myInline.is_valid():
            myInline.save()
            myform.save()
            return HttpResponseRedirect(...)
    myInline = inlineFormset(request.POST)
else:
    myform = new form from model etc...
    myInline = new inline formset from model etc...
return render_to_respose(template.html, 'myform':myform, 'myInline':myInline, context_instance=RequestContext(request))

在退出主要的if 语句之前,我只是潜入一个新的myInline 分配。

希望这可以帮助其他人解决同样的问题。

干杯!

【问题讨论】:

如果你自己想出了答案,你可以发布一个答案并接受它作为正确答案(这样问题就结束了!) 好电话。 (我还是新手)我的答案贴在下面。 【参考方案1】:

好的,我知道如何显示myForm 主表单的验证错误并重新显示所有myForm 字段以及myInline 表单集字段。它是这样的:

if request.method=='POST':
    myform = Model_Form(request.POST)
    if myform.is_valid():
        tmp = myform.save(commit=False)
        myInline = inlineFormset(request.POST, instance=tmp)
        if myInline.is_valid():
            myInline.save()
            myform.save()
            return HttpResponseRedirect(...)
    myInline = inlineFormset(request.POST)
else:
    myform = new form from model etc...
    myInline = new inline formset from model etc...
return render_to_respose(template.html, 'myform':myform, 'myInline':myInline, context_instance=RequestContext(request))

在退出主要的if 语句之前,我只是潜入一个新的myInline 分配。

希望这可以帮助其他人解决同样的问题。

干杯!

【讨论】:

以上是关于带有内联表单集的 Django 表单验证的主要内容,如果未能解决你的问题,请参考以下文章

python Django:验证主要表单中的内联表单

django 内联表单集的单选按钮

Django 表单验证:在父表单中获取子表单数据

如何使用 django-extra-views 将请求传递到内联表单集中

Django - 禁用表单选择字段验证

带有外键的 django 自定义表单验证