2017-04-19 34 views
0

我試圖找到如何建立代表一個模型提出以下指導意見:Django的模型強制性/ excatly一個交叉表關係

  • 我們的IT環境(包括多個組件,如Web服務器,數據庫,等等)
  • SLA並非特定於一個環境,它更多是一組具體環境引用的一般合同(又名應該是一個單獨的表)
  • 每個環境必須至少有一個或多個SLA(s)關聯
  • 來自所有SLA員工d到的環境正好一個必須具備的狀態「有效」

我實現了一個模型,充分反映了第一個兩分(至少我是這麼認爲的),尤其是最後一點似乎很麻煩。

足夠的意思,使用此實現,使用交叉表的關係是可選,不是強制性的。目前這還不錯,但從長遠來看不會。

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) 

所以我的問題是:

  • 難道我通常在正確的軌道上,但拍攝最後一個約束是不可能僅僅專注於模型?

  • 什麼是優雅的方式?

回答

0

我們實施了,做以下的模型EnvironmentSLA保存()方法:

  1. 檢查,如果要保存的對象集合狀態==有效
    1. 如果不只是救物體
  2. 試圖獲得當前有效的SLA
  3. chang E中的當前有效的SLA的SLA狀態不推薦的
  4. 保存對象

的保存() - 函數如下:

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。