2011-06-29 26 views
2

我是Django和MySQL的新手,所以我很抱歉,如果這最終是一個簡單的問題。Django:需要數據庫架構方面的幫助(ManyToMany,ForeignKey關係)

我正在項目管理網站上工作。假設我們有一個Program。每個程序都有一些編號爲Milestones,其中有一些編號爲Tasks需要完成才能達到里程碑。里程碑在不同的程序中是相同的,但不能保證每個里程碑所需的任務在各個程序中保持不變。

下面是一個(略)models.py

class Program(models.Model): 
    # ... 
    complete = models.BooleanField() 
    milestones = models.ManyToManyField(Milestone, through='ProgramMilestone') 

class Milestone(models.Model): 
    # ... 

class Task(models.Model): 
    # ... 
    complete = models.BooleanField() 
    milestone = models.ForeignKey(Milestone) 

class ProgramMilestone(models.Model): 
    # ... 
    complete = models.BooleanField() 
    program = models.ForeignKey(Program) 
    milestone = models.ForeignKey(Milestone) 

...through='ProgramMilestone'因爲Programs應該允許共享Milestones,但有按程序完成狀態。

這種模式的問題是這樣的:

  • 我們有兩個方案,方案1和方案2
  • 方案1有上的一個里程碑,並計劃2也具有里程碑A.
  • 添加任務計劃1的里程碑A.
  • 不需要的後果:現在的任務也連接到節目2的里程碑A.

解決方案可能是在Milestone數據庫中創建兩個「Milestone A」:兩個不同的行共享名稱「Milestone A」。然而,考慮到它們只會在id中有所不同,同時是相同的概念性項目,這似乎是一種浪費。

另一個想法可能是既需要ProgramIDMilestoneID添加新Task時,但當時我不知道人們可能會在Django管理添加新的任務 - 那就是,如何通過該計劃的ProgramID該用戶目前正在查看。

我該如何修改我的models.py,以便程序可以在每個程序集中爲每個程序設置任務時共享里程碑(即避免上述情況)?

回答

1

既然你想要的任務可能與計劃的里程碑,而不是里程碑,你可以類任務更改爲:

class Task(models.Model): 
    # ... 
    complete = models.BooleanField() 
    programMilestone = models.ForeignKey(ProgramMilestone) 
+0

哦天啊,我甚至不知道你可以鏈接到的ForeignKey通表。我有一種感覺,這就是我正在尋找的,但我會檢查並確認,如果是,請給你打個勾。謝謝! –

0

從我的(外)的角度看,命名是不是你真正想要成爲什麼定義你的數據庫模式。程序1下的里程碑A雖然名稱相同,但它與程序2下的「相同」里程碑A可以有完全不同的一組任務。

我建議你做的是區分鍵名和顯示名稱。例如,在Milestone模型中,您可以有兩個名稱:MilestoneKey,它將在內部使用並存儲爲「Program 1 Milestone A」之類的內容,MilestoneName則類似於「Milestone A」。

在您的應用程序中,用戶只會看到MilestoneName,而在內部您可以將其跟蹤爲MilestoneKey。

或者,爲了避免複雜性,只是有MilestoneName場,並調用方案2的里程碑A成爲里程碑X,或計劃2 - 里程碑A.