2012-02-05 53 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)。