2012-11-23 157 views
1

我有一個自引用許多一對多的關係,像這樣:Django的許多一對多的關係排列關係

class User(models.Model): 
    groups = models.ManyToManyField('self', blank=True, null=True) 

當我創建用戶1和用戶2之間的關係,這是雙向的。我可以看到這一點:

User_1_obj.groups.all() 
User_2_obj.groups.all() 

然而,當我添加用戶到3使用的關係:

User_1_obj.groups.add(User_3_obj) 

用戶1和用戶3雙向聯繫。但是我也希望用戶2和用戶3(以及關係中的任何其他用戶被鏈接)。換句話說,我希望所有的排列進行相互鏈接,其中:

User 1 linked to User 2, User 3, User 4 
User 2 linked to User 1, User 3, User 4 
User 3 linked to User 1, User 2, User 4 
User 4 linked to User 1, User 2, User 3 

有沒有一種簡單的方法來做到這一點不是通過所有的鏈接,並添加缺少connectinos迭代?

謝謝!所有的幫助表示讚賞。

+0

你有這個理由需要這樣做嗎?創建可以引用User實例的「Group」模型有什麼不妥? –

+0

嘿馬庫斯,謝謝你的回覆。不確定我瞭解如何設置組模型並覆蓋用戶之間的所有排列鏈接?如果您能澄清 –

+0

,我將不勝感激您是否嘗試將新用戶添加到所有現有用戶? –

回答

0

我想你在錯誤的情況下使用自我指涉關係。如果您試圖在用戶之間建立任意的無向圖連接,則自我參照關係很有用。

如果連接到用戶意味着您自動連接到所有其他用戶,並且所有這些連接在語義上完全等效,那麼在我看來,您正試圖定義更類似於圖形的東西,其中completeconnected components。如果是這種情況,那麼每個用戶實際上只能屬於一個組。

可能這樣做與你的計劃,但你可以看到,這將需要大量的手動管理強制完全連接的條件,過度描述。向更好的方向邁出的一步是通過分組一個簡單的字段,比如可以爲空的IntegerField。

class User(models.Model): 
    group = models.IntegerField(null=True) 

然後,你可以僅僅通過User.objects.filter(group=myUser.group)在同一組給定的myUser查詢所有用戶。唯一棘手的部分是,如果以前未連接的組中的兩個用戶連接,您將不得不一次爲一羣用戶重新分配組。但是,您可以執行bulk update將第二組中的所有用戶重新分配給第一個用戶,以合併這些組。

您需要自問的一個問題是,用戶是否與同一組中的任何其他用戶斷開連接會導致該用戶與該組中的所有用戶斷開連接。

0

如果你的目標是得到所有其他用戶,不包括你已經有實例,那麼這將這樣的伎倆:

class User(models.Model): 
    def groups(self): 
     return User.objects.exclude(pk=self.pk) 

不過,如果你只想搜索User情況下的一個子集你可以創建一個名爲Group的第二個模型。 (這一切都似乎有點光顧,因爲我們現在基本上覆制django.contib.auth.models。)

class Group(models.Model): 
    # Some attributes you would like (maybe a name, or code) 

class User(models.Model): 
    groups = models.ManyToManyField(Group, related_name='users') 

    def get_linked_users(self, group): 
     return group.users.exclude(pk=self.pk) 

什麼你想實現的是太模糊定義,但這些都是一對夫婦的方式來表示在Django實例之間的關係。


但我不確定,排列應該在數據庫中表示。我只想回顧一下我希望包含的所有User對象,然後用Python解決事後的變化。

也許你可以進一步瞭解這種嘗試背後的原因。也許有一個更簡單的方法。