2012-02-05 45 views
1

我有一个模型w/a manytomany关系到另一个模型。他们都有与他们相关的形式,后者有一个formset。保存manytomanyfield与modelformset

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小部件被替换为formset。因此,我必须手动将在该formset中指定的Bar实例与Foo的ManyToManyField关联。我在Foo的清洁方法,这样做:

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设置为formset中已更改的窗体集。因此,如果我添加一个酒吧到我的foo,然后重新加载表单并添加第二个酒吧,foo只会有第二个酒吧。

根据Django文档:

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

所以我明白为什么我的代码是失败。我只是不知道该怎么办。我可以通过什么方式传递给cleared_data [“bars”],它将添加新修改的表单,但不会删除现有的表单?

非常感谢您的帮助。

+0

**十五分钟后...... ** 分配这cleaned_data [“条”] _seems_是工作,但感觉那种哈克:如果表格 '[form.instance的形式barFromSetInstance。 cleaned_data]' – trubliphone 2012-02-05 08:05:52

回答

0

这是值得的,上面的评论有错误。还有一些我忽略的细节。

适当的代码看起来是这样的:

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 

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

相关问题