2014-01-15 93 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

我添加了一个更新。 –