2014-01-15 97 views
1

我被卡住了,需要一些新的眼睛在我的模型設計。我似乎無法圍繞如何最好地設計這個問題。Django模型設計使用ForeignKey和ManyToMany

REQS:

  • 每個項目都可以有主動服務若干個等級的同時,與其他被設置爲關閉。沒有互斥
  • 所有項目的層次都是一樣的。
  • 我需要跟蹤特定項目上活動的層次。
  • 我需要能夠將項目的收費日期與活動層相關聯。請參閱下面的收費日期澄清。
  • 項目和層'活動'字段不相關。
  • 請參閱編輯以瞭解更多有關我的需求的想法。

這裏的模型:

class Project(models.Model): 
    name = models.CharField('project name', max_length=128) 
    company = models.ForeignKey('Company', related_name='projects') 
    # A project could have more than one instance 
    instances = models.ManyToManyField(Instance, related_name='projects') 
    type = models.CharField(max_length=128, blank=True) 
    start_date = models.DateField(null=True, auto_now=False, auto_now_add=False) 
    end_date = models.DateField(null=True, auto_now=False, auto_now_add=False) 
    active = models.BooleanField() 

class Tier(models.Model): 
    TIERS = (('TI1', 'tier1'), 
      ('TI2', 'tier2'), 
      ('TI3', 'tier3'), 
      ('TI4', 'tier4'), 
      ('TI5', 'tier5')) 

    name = models.CharField(max_length=3, choices=TIERS) 
    active = models.BooleanField() 

class TierHistory(models.Model): 

    project = models.ForeignKey(Project, related_name='tier_history') 
    tiers = models.ManyToManyField(Tier) 
    charge_date = models.DateField(null=True, auto_now=False, auto_now_add=True) 
    contact = models.ForeignKey(Contact) 

一個編輯來澄清一些事情:

我遇到的是,鑑於目前設計的問題,我不覺得我跟蹤層次,以及他們是否以最佳方式活躍。這是所有這一切的主要目標;瞭解項目中哪些層次是活躍的,反過來能夠看到哪些項目曾經活躍過任何特定層次。

鑑於我目前的設計,我不能設置2級活躍項目1和不活躍的項目2

  • 一個項目可以有多個活動的層次同時進行。
  • 收費日期將用於每一層。我意識到我讀了我的規格錯誤。
  • 我需要能夠報告,「項目1已使用第1層爲3個月,第2層爲6個月,從未使用第5層」
  • 我需要能夠報告,「項目1和項目2有1級有源現在,項目1有4層活躍的1個月,項目3項,目前正在使用第5" 級
+0

你說你被卡住了 - 這個設計是什麼問題導致你?您提到項目的'a'收費日期,但由於'TierHistory'對'Project'有一個'ForeignKey',因此每個項目可以有多個'TierHistories'和'charge_dates' - 是您想要的嗎? –

+0

@KevinChristopherHenry,我對我最初的問題進行了編輯,以澄清我的問題並指定我需要每層的每層收費日期。 – yubus

回答

0

根據你想問的問題,這聽起來像你需要保持一個給定層狀態的所有變化的完整歷史記錄。有很多方法可以做到這一點,這是一個簡單的方法。基本的想法是,每次你改變一個層次的狀態時,你都會創建一個新的TierState

(請注意,這是不完全正常化,因爲currentchange_time隱含的。它使查找更輕鬆,狀態變化稍硬。)

class Project(models.Model): 
    # as before 

class TierState(models.Model): 
    TIERS = (('TI1', 'tier1'), 
      ('TI2', 'tier2'), 
      ('TI3', 'tier3'), 
      ('TI4', 'tier4'), 
      ('TI5', 'tier5')) 

    project = models.ForeignKey(Project, related_name='tiers') 
    name = models.CharField(max_length=3, choices=TIERS) 
    active = models.BooleanField() 
    change_time = models.DateTimeField(auto_now_add=True) 
    current = models.BooleanField() 

是1級活躍項目1?

project1.tiers.filter(name='TI1', active=True, current=True).exists() 

設置三級活躍項目2

# For simplicity, assume a current state exists. Also, wrap this in a transaction. 
current_t3 = project2.tiers.get(name='TI3', current=True) 
current_t3.current = False 
current_t3.save() 
project2.tiers.create(name='TI3', active=True, current=True) 

先後項目1個使用過的第5級?

project1.tiers.filter(name='TI5', active=True).exists() 

多久了項目2使用了4級?

# For simplicity we'll just assume it's active 
datetime.now() - project2.tiers.get(name='TI4, current=True).change_time 

什麼是目前使用級3個項目?

Project.objects.filter(tiers__name='TI3', tiers__active=True, tiers__current=True) 
+0

感謝您花時間回覆並輸入了所有內容。 此TiersState模型將代替我在第一個問題中的層級和層級歷史模型,對不對? 只是爲了確保我得到這個,這裏有一個場景: 項目1當前有第一層活動層,第二層活動層,過去有第四層活躍層,但是當前處於非活動狀態。 我會爲每個階段變得活躍的時間記錄一個條目,共有6個條目? (即,項目1的TierState中不會有條目3和4) – yubus

+0

@yubus:是的,只有這兩個模型。如果你有任何一個數據層以外的其他標籤,你會想把它分解到它自己的表中。至於你的情況,因爲你正在記錄狀態*變化*你將有10個'TierHistory'條目:1層(開),2層(開)和5層(開,關,開,關,開,關,開關)。爲了讓生活更輕鬆,當你創建一個新的'Project'時,你可能想爲每一層創建一個開始的'TierHistory'(關閉)條目。這樣,您不必通過查看條目是否已存在而使邏輯複雜化。 –

0

我需要跟蹤什麼層次的唯一項目是活躍在特定的項目

爲此,請將ManyToManyField添加到項目模型中。通過這樣做,因爲你可以一次只能選擇一項,那麼當你把這個項目對象和對象的層次,你將獲得當前活動層:

class Project(models.Model): 
    tier = models.ManyToManyField(Tier) 
    # other fields in your Project Model 

我需要能夠將項目的收費日期與活動層相關聯。

這需要是一個單獨的交易表。所以你需要一個帶有這些字段的表格:

Charge Date, ProjectID (PK of your Project Model - unique identifier), Active Tier at the time. 

當費用發生時,寫入此表以記錄交易。

UPDATE

我勸然後使每一級布爾字段。這樣他們可以隨意打開和關閉。一次可以有多個層次。

要知道哪些層更改時,可以將其放入先前推薦的事務表中。根據Project創建一個類方法來處理這個問題。或者只是查詢你數據庫中的數據。

+0

我添加了一個編輯到我最初的問題,試圖澄清問題。我需要每個項目的每個層次的收費日期,每個項目最多可以有5個層級活躍,或者只有一個活動層級。 我認爲一個交易表可能會工作,以保持每個層次和項目的收費日期 – yubus

+0

我添加了一個更新。 –