Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 强制/例外一交叉表关系的Django模型_Python_Django_Model - Fatal编程技术网

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)
因此,我的问题是:

  • 我的思路是否正确,但仅仅关注模型不可能捕捉到最后一个约束

  • 什么是优雅的方式

我们为模型环境SLA实现了一个save()方法,该方法执行以下操作:

  • 检查要保存的对象是否设置为state==EFFECTIVE
  • 如果不只是保存对象
  • 尝试获取当前有效的SLA
  • 将当前有效SLA的状态SLA更改为不推荐
  • 保存对象
  • save()-函数如下所示:

    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