我有一个产品型号和一个价格模型。价格模型对产品型号有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的实例,“父”或容器 对于租户和自我来说是
的一个例子class BaseBuildingFormset(BaseInlineFormSet)
实例化如下:
BuildingFormset = inlineformset_factory(models.Block,
models.Building,
formset=BaseBuildingFormset,
extra=1)
为了解决这个问题,我停止了传递self.data, 这导致了最低的形式 即使在渲染之后,图层也始终具有is_bound = False 张贴回视图。因此验证总是失败而且 表单所代表的对象无法更新。我转载了 使用Nathan的博客文章中的代码的行为,所以似乎 嵌套表单集的这种方法不再有效,或者代码需要 调整工作在1.3。
直到Django 1.2.5,Nathan的代码运行良好。但是在1.3,如果self.data 传递给TenantFormset,结果是空的和ValidationError 是因为尚未提供ManagementForm信息而引发的 这是#11418,AFAICT的预期后果。
有没有人对如何使其工作有任何其他想法?
干杯,
(很抱歉没有详细的代码示例 - 内森的帖子很多 比我的代码更清晰,所以我建议你看一下。)
一般注意:关于如何执行此操作似乎有很多困惑,这里的回复显示http://www.reddit.com/r/django/comments/hwyto/is_there_a_way_to_do_nested_formsets_in_django/
答案 0 :(得分: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)]
答案 1 :(得分:0)
我目前正在尝试同样的事情。我从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)
但是我仍然会得到一张空白的表格。
答案 2 :(得分: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。