首页 文章

django 1.3中内联formset的formset

提问于
浏览
0

我有一个产品型号和一个价格模型 . 价格模型对产品型号有FK . 可能有多个价格(取决于销售的单位数量) . 以前django 1.2.5 http://yergler.net/blog/2009/09/27/nested-formsets-with-django/会解决这个问题 . 但详细http://www.mail-archive.com/django-users@googlegroups.com/msg124195.html这不再有效 .

结束所需结果:以下表单用于编辑和添加数据 .

产品一 - 价格一,数量 - 价格二,数量产品二 - 价格一,数量产品三 - 价格一,数量 - 价格二,数量 - 价格三,数量

为清晰起见,转载:

在Nathan的原始代码中,最低级别的formset创建如下:

TenantFormset(data=self.data,
              instance=instance,
              prefix='TENANTS_%s' % pk_value)

其中instance是Building的实例,tenant的“父”或容器是self的一个实例

class BaseBuildingFormset(BaseInlineFormSet)

这是实例化的:

BuildingFormset = inlineformset_factory(models.Block,
                                        models.Building,
                                        formset=BaseBuildingFormset,
                                        extra=1)

为了解决这个问题,我停止了传入self.data,这导致最低层中的表单始终具有is_bound = False,即使在渲染并POST回到视图之后也是如此 . 因此,验证总是失败,并且表单所代表的对象无法更新 . 我使用Nathan的博客文章中的代码重现了这种行为,所以似乎这种嵌套表单集的方法不再有效,或者代码需要调整才能在1.3下工作 .

直到Django 1.2.5,Nathan的代码运行良好 . 但是在1.3时,如果将self.data传递给TenantFormset,则结果为空,并且由于尚未提供ManagementForm信息而引发ValidationError .
这是#11418,AFAICT的预期结果 .

有没有人对如何使其工作有任何其他想法?

干杯,

(抱歉没有详细的代码示例 - Nathan的帖子比我的代码更清晰,所以我建议你看看 . )

一般说明:关于如何做到这一点似乎有很多困惑,这里的回答显示http://www.reddit.com/r/django/comments/hwyto/is_there_a_way_to_do_nested_formsets_in_django/

3 回答

  • 2

    正如django docs所说,如果表单没有绑定,则必须传递data = None:

    data = None
    if self.data:
        data = self.data
    form.nested = [ModelXYFormset(data=data, instance = instance, prefix = 'opt%s' % pk_value)]
    
  • 0

    我'm currently attempting the same thing. I had implemented the same solution from Nathan'的代码,但遇到了 ValidationError 问题 . 打开我们的Django 1.3更新了formset的工作方式,如here所示 . 所以对于我的代码,

    TenantFormset(data=self.data, instance=instance, prefix='TENANTS_%s' % pk_value)
    

    TenantFormset(instance=instance, prefix='TENANTS_%s' % pk_value)
    

    但我仍然得到一张空白的表格 .

  • 0

    这是一个解决方案,似乎可以使子子表单验证 .

    在BaseBuildingFormset中:

    def is_valid(self):
        result = super(BaseProtocolEventFormSet, self).is_valid()
    
        for form in self.forms:
            if hasattr(form, 'nested'):
                for n in form.nested:
                    n.data = form.data
                    if form.is_bound:
                        n.is_bound = True
                    for nform in n:
                        nform.data = form.data
                        if form.is_bound:
                            nform.is_bound = True
                    # make sure each nested formset is valid as well
                    result = result and n.is_valid()
        return result
    

    每个表单和表单集的数据应该相同(完整的POST数据) . 在这里,我们手动设置这个没有得到它的表单 . 我们还可以看到,在BaseForm类中,is_bound只是验证表单是否包含数据或文件,因此一旦表单有数据,我们就将其设置为true .

相关问题