2013-08-16 148 views
0

我正在使用Django 1.5,我正在努力與我認爲是非常基本的東西。Django遞歸關係

我有以下人員模型:

class Person(models.Model): 
    contact_person = models.ManyToManyField(ContactPerson) 
    first_name = models.CharField(max_length=30) 
    last_name = models.CharField(max_length=30) 
... 

的目標是將人的夥伴添加到模型。我不希望這個夥伴或這個人優於另一個;他們應該是平等的。 換句話說,當查找一個人時,他/她的伴侶也應該出現(如果有的話)。我需要能夠在女性或男性方面添加一次伴侶(我不想將它們連接兩次)。

我搜索過OneToOneFields的文檔,但似乎遞歸OneToOnes不被支持,即我得到一個NameError(「名‘人’沒有定義」),當我嘗試:

partner = models.OneToOneField(Person, blank=true, null=true) 

任何人都可以將我指向正確的方向嗎?

+0

可以了'Person'是'其他幾個'Persons'的parent'?或只允許1個'兒子'。 –

+1

其實我不需要/想要父母與太陽的關係。我想要一個合作伙伴等同於一個人(無論如何,合作伙伴都是一個人)。 – SaeX

回答

3

試試這個:

class Person(models.Model): 
    first_name = models.CharField(max_length=30) 
    last_name = models.CharField(max_length=30) 
    ... 
    partner = models.OneToOneField('self', null=True, blank=True) 

    def save(self, checkPartner = True, *args, **kwargs): 
     super(Person, self).save() 
     if self.partner and checkPartner: 
      self.partner.partner = self 
      self.partner.save(checkPartner = False) 
  • 對於合作伙伴字段爲空,必須啓用,因爲要保存的第一個人將沒有任何合作伙伴。
  • checkPartner參數已被添加,使保存()不屬於一個無限循環
2

https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey

partner = models.OneToOneField('Person', blank=true, null=true) 

或替代,如果你在同一類

partner = models.OneToOneField('self', blank=true, null=true) 

報價是一切,在這種情況下

def save(self, *args, **kwargs): 
    # call to super, we want self.partner to be set 
    super(Person, self).save(*args, **kwargs) 

    # this is necessary to avoid infinite save loops on partner's save call 
    # at this point, you have a partner 
    # this won't work if your partner has already a partner 
    # but it's easy to go from here 
    if not self.partner.partner: 
     self.partner.partner = self 
     self.partner.save() 
+0

謝謝,但是在這種情況下,當爲一個人挑選一個伴侶(人2)時,人2不會自動鏈接到人1。這就是我所害怕的。 – SaeX

+0

你想在person1更新personkey後更新foreignkey? –

+0

我認爲這的確如此。一旦我爲這兩個人中的任何一個選擇一個合作伙伴(假設person2被選爲person1的合作伙伴),那麼我不想去partner2並選擇partner1作爲他/她的夥伴。 – SaeX