Python 强制/例外一交叉表关系的Django模型
我试图找到关于如何构建代表以下内容的模型的指导:Python 强制/例外一交叉表关系的Django模型,python,django,model,Python,Django,Model,我试图找到关于如何构建代表以下内容的模型的指导: 我们有IT环境(由多个组件组成,如Web服务器、数据库等) SLA不是特定于一个环境的,它更多的是一组通用合同,一个具体的环境引用(aka应该是一个单独的表) 每个环境必须至少有一个或多个关联的SLA 从与环境关联的所有SLA中,只有一个必须具有“有效”状态 我实现了一个充分反映前两点的模型(至少,我认为是这样),但特别是最后一点似乎很麻烦 充分地说,使用这个实现,使用交叉表的关系是可选的,而不是强制性的。目前这是可以的,但从长远来看不是 c
- 我们有IT环境(由多个组件组成,如Web服务器、数据库等)
- SLA不是特定于一个环境的,它更多的是一组通用合同,一个具体的环境引用(aka应该是一个单独的表)
- 每个环境必须至少有一个或多个关联的SLA
- 从与环境关联的所有SLA中,只有一个必须具有“有效”状态
class Environment(models.Model):
fullname = models.CharField(max_length=45)
...
sla = models.ManyToManyField(SLA, through='EnvironmentSLA')
creation_date = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = (('fullname', 'projectid', 'regionid', 'account'),)
class SLA(models.Model):
description = models.CharField(max_length=255)
reaction_time = models.CharField(max_length=45)
service_level = models.CharField(max_length=45)
creation_date = models.DateTimeField(auto_now_add=True)
class EnvironmentSLA(models.Model):
PLANNED = 'pl'
EFFECTIVE = 'ef'
DEPRECATED = 'dp'
SLA_STATE = (
( PLANNED, 'planned' ),
( EFFECTIVE, 'effective'),
( DEPRECATED, 'deprecated'),
)
environment = models.ForeignKey('Environment', on_delete=models.CASCADE)
sla = models.ForeignKey(SLA, on_delete=models.CASCADE)
state = models.CharField(max_length=2, choices=SLA_STATE, default=PLANNED)
因此,我的问题是:
- 我的思路是否正确,但仅仅关注模型不可能捕捉到最后一个约束
- 什么是优雅的方式
class EnvironmentSLA(models.Model):
[...]
def save(self, *args, **kwargs):
if self.state != self.EFFECTIVE:
super(EnvironmentSLA, self).save(*args, **kwargs)
return
try:
effective_sla = EnvironmentSLA.objects.filter(environment=self.environment, state=self.EFFECTIVE).get()
except Exception as e:
effective_sla = None
if effective_sla:
effective_sla.state = self.DEPRECATED
effective_sla.save()
super(EnvironmentSLA, self).save(*args, **kwargs)
这样,我们就不会丢失已定义的SLA,而是始终只有一个活动SLA