2014-09-25 31 views
0

我有這樣看起來是這樣一種模式:Django - ManyToMany中的對稱ForeignKeys或級聯刪除?

class Bar(models.Model): 
    foo1 = models.ForeignKey(Foo, related_name='bar_foo1') 
    foo2 = models.ForeignKey(Foo, related_name='bar_foo2') 

    class Meta: 
     unique_together = ('foo1', 'foo2') 

問題是foo1foo2需要有相同的行爲,他們被反轉時。換句話說,就是這樣的:「如果你喜歡foo1,你可能想檢查foo2」,應該以其他方式應用(「如果你喜歡foo2,你可能想檢查foo1」)。

所以我用一個多對多場,而不是ForeignKey的,使它們對稱:

class Bar(models.Model): 
    foos = models.ManyToManyField(Foo) 

的信號以確保有從來沒有超過2 foos

def foos_changed(sender, **kwargs): 
    if kwargs['instance'].foos.count() > 2: 
     raise ValidationError("You can't assign more than two foos.")  

m2m_changed.connect(foos_changed, sender=Bar.foos) 

不過,這會另一個問題是,如果foos中的Foo被刪除,Bar只是停留在那裏,但它也應該被刪除(這是通過在ForeignKeys中級聯刪除來解決的)。

我該如何解決這個問題?我可以使ForeignKeys對稱嗎?或者在ManyToMany中實現級聯刪除?還是有另一種方法來解決這個問題?

回答

2

我以前做過這件事,最簡單的方法是爲模型實例創建一個僞構造函數,以確保項目1和項目2始終按順序排列(我使用的是字母順序,但您也可以使用id),這使得你的獨特性工作。

在查找中,您只需在foo1或foo2中查找您的項目,因爲您不介意它是關係的哪一側,它提供了雙向性。

在這裏和那裏有幾個助手,你有一個智能對象,提供建議。

另一個更具擴展性的方法是創建一個僅包含推薦組名稱的表,然後將m2m對象提供給推薦組,以便推薦一組foos,查找更容易:foo - > group - >許多foos

+0

偉大的解決方案!非常感謝你! – Filly 2014-09-25 13:47:56