我被困住了,需要对我的模型设计有一些新的认识。我似乎无法理解如何最好地设计它。
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)
清理事项的编辑:
我遇到的问题是,鉴于目前的设计,我不觉得我正在跟踪层级,以及它们是否以最佳方式运行。这是所有这一切的主要目标;了解项目中哪些层是活动的,相反能够看到哪些项目曾经活跃过任何特定层。
鉴于我目前的设计,我不能在项目1上设置第2层活动而在项目2上设置不活动。
答案 0 :(得分:0)
我需要跟踪特定项目中哪些层级处于活动状态
为此,请将ManyToManyField添加到项目模型中。通过这样做,因为您一次只能选择一个选项,那么当您调用Project对象和该对象的层时,您将获得当前活动层:
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.
当收费发生时,写入此表以记录交易。
<强>更新强>
我建议然后将每个Tier设为布尔字段。这样他们就可以随意打开和关闭。并且您可以一次打开多个层。
要知道何时更改了哪个层,您可以将其放在事先建议的事务表中。在Project
下创建一个类方法来为您处理此问题。或者只是查询数据库中的数据。
答案 1 :(得分:0)
根据您想问的问题,听起来您需要保留对给定层状态的所有更改的完整历史记录。有很多方法可以做到这一点,这是一个简单的方法。基本思想是,每次更改层的状态时,都会创建一个新的TierState
。
(请注意,这并未完全规范化,因为current
隐含了change_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中将第3层设置为活动。
# 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)