【问题标题】:save manytomanyfield with modelformset使用 modelformset 保存 manytomanyfield
【发布时间】:2012-02-05 07:03:36
【问题描述】:

我有一个模型与另一个模型具有多对多关系。它们都有与之关联的表单,后者有一个表单集。

 class Foo(models.Model):
   name = models.CharField(max_length=20)
   bars = models.ManyToManyField("Bar",blank=True,null=True)

 class Bar(models.Model):
   name = models.CharField(max_length=20)

 class FooForm(ModelForm):
   class Meta:
     model = Foo

 class BarForm(ModelForm):
   class Meta:
     model = Bar

 BarFormSet = modelformset_factory(Bar,form=BarForm,extra=2)

在我的视图/模板中,标准的 ManyToManyField 小部件已替换为表单集。因此,我必须手动将该表单集中指定的 Bar 实例与 Foo 的 ManyToManyField 相关联。我在 Foo 的 clean 方法中这样做:

 def clean(self,*arg,**kwargs):
   cleaned_data = self.cleaned_data
   # barSubFormInstance is the BarSubForm that is displayed in my view
   if barFormSetInstance.is_valid(): 
     barInstances = barFormSetInstance.save()
     cleaned_data["bars"] = barInstances
   return cleaned_data

几乎有效。问题在于它将 Foo.bars 设置为表单集中已更改的表单集。因此,如果我在 foo 中添加一个 bar,然后重新加载表单并添加第二个 bar,则 foo 最终只有第二个 bar。

根据 Django 文档:

save() 方法返回已保存到数据库的实例。如果给定实例的数据在绑定数据中没有变化,则该实例不会保存到数据库中,也不会包含在返回值中...

所以我明白为什么我的代码失败了。我只是不知道该怎么办。我可以将什么传递给cleaned_data["bars"] 以添加新修改的表单但不删除现有表单?

非常感谢您的帮助。

【问题讨论】:

  • 15 分钟后... 将此分配给cleaned_data["bars"] 似乎 工作,但感觉有点hacky:@ 987654323@

标签: django manytomanyfield django-forms formset


【解决方案1】:

对于它的价值,上面的评论有一个错误。还有一些我遗漏的细节。

相应的代码如下所示:

def clean(self,*arg,**kwargs):
   cleaned_data = self.cleaned_data
   # barFormSetInstance is the BarFormSet that is displayed in my view
   # it's already been validated by the time this function is called
   barInstances = [form.save() for form in barFormSetInstance if form.cleaned_data]
   cleaned_data["bars"] = barInstances
   return cleaned_data

我还必须确保 ManyToManyField 的“空白”和“空”都设置为 True。 (我不知道为什么我必须这样做,而不是重写该字段的 is_valid() 方法来只返回 True)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-21
    • 2020-05-11
    • 2013-07-09
    • 2020-11-15
    • 2019-02-06
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    相关资源
    最近更新 更多