2010-09-11 25 views
0

我的例子(我知道這不是技術上是正確的,它僅僅是一個例子):Django的倍數關係到單一數據模型

class ipAddy(models.Model): 
    network=models.ForeignKey(network) 
    ipAddy=models.IPAddressField(foo) 

class device(models.Model): 
    hostname=models.CharField(foo) 
    foo=models.CharField(bar) 
    bar=models.CharField(foo) 

    class Meta: 
     abstract = True 

class linuxServer(device): 
    linuxInfo - models.CharField(foo) 

class macServer(device): 
    macInfo = models.CharField(foo) 

我的目標:

對於每一個基於設備的模型有很多與ipAddy模型的一對一關係。在現實世界中說:我希望每種類型的服務器或設備都能夠擁有多個IP地址。

在Django 1.2中完成此操作的最佳方法是什麼?

所有的建設性的想法,讚賞。

回答

1

執行此操作的最明顯方法是將多對多字段添加到抽象類device。事情是這樣的:

class device(models.Model): 
    hostname=models.CharField(foo) 
    foo=models.CharField(bar) 
    bar=models.CharField(foo) 
    ip_addresses=models.ManyToManyField(ipAddy) # <=== m2m 

    class Meta: 
     abstract = True 

上述結構假定您不希望任何其他附加與許多信息存儲到一對多的關係。

如果你想要附加更多的數據到每個多對多的關係,那麼你可以使用intermediary table。這不能用抽象類來完成。它必須在兒童模型級完成。對於例如

class linuxServer(device): 
    linuxInfo = models.CharField(foo)   
    ip_addresses=models.ManyToManyField(ipAddy, 
      through='LinuxIPAssociation') # <=== m2m 

    class Meta: 
     abstract = True 

class LinuxIPAssociation(models.Model): 
    device = models.ForeignKey(linuxServer) 
    ip_addy = models.ForeignKey(ipAddy) 
    custom_field_1 = models.CharField(...) 
    custom_field_2 = models.IntegerField(...) 

# Similarly for Mac also. 

原因上面的是你使用中間表和Django不容許你申報的外鍵的抽象模型類時需要一個外鍵兩種型號。因此你必須自己申報兩個獨立的中間模型。

PS:您使用小寫的類名稱正在擾亂我。停止並停止!

+0

謝謝你的想法。 ManyToManyField確實構建出來了,但它需要讓數據庫中定義的每個IP地址都被滾動瀏覽,以選擇您想要在給定設備上使用的地址。只是不實際的解決方案。 – jduncan 2010-09-11 15:49:21

+0

第二個建議(再次感謝)有一個循環引用,不是嗎? linuxServer類正在引用LinuxIPAssociation類,該類尚不存在......對吧? – jduncan 2010-09-11 15:50:14

+0

'linuxServer類引用的LinuxIPAssociation類尚不存在......對嗎?':正確。這就是爲什麼這個班的名字是用引號引起來的。您可以在文檔中看到類似的示例:http://docs.djangoproject.com/en/dev/topics/db/models/#extra-fields-on-many-to-many-relationships – 2010-09-12 07:47:30