2014-02-19 71 views
0

這是一個設計問題。重新將模型重新設置爲嘗試捕獲

假設一個組織的名稱和代碼

class Organisation(models.Model): 
    """ 
    Class to manage Organisations. 
    """ 
    name = models.CharField(_('Name'), max_length=50) 
    code = models.CharField(_('Code'), 
      max_length=8, 
      editable=False, 
      unique=True) 

爲了避免代碼的問題,我用這個方法保存:

def save(self, *args, **kwargs): 
    """ override save method to add specific values """ 
    if self.pk is None: 
     self.code = strftime('%y%m')+str(uuid4())[:4] 
    try: 
     super(Organisation, self).save(*args, **kwargs) 
    except IntegrityError: 
     self.code = strftime('%y%m')+str(uuid4())[:4] 
     super(Organisation, self).save(*args, **kwargs) 

正如你可以想像,這個代碼不工作,這是一個錯誤的代碼,但我不知道該怎麼辦:'( 編輯:代碼格式是一個約束,我不能改變它

回答

1

正如我已瞭解它,你得到的是否是IntegrityError因爲你code必須是唯一的。 你可以在save方法過濾,如果使用相同的代碼實例已經存在:

def _generate_code(self): 
    # have the whole code generation in one place 
    return strftime('%y%m')+str(uuid4())[:4] 

def save(self, *args, **kwargs): 
    if self.pk is None: 
     self.code = self._generate_code() 
     while Organisation.objects.filter(code=self.code).exists(): 
      self.code = self._generate_code() 
    super(Organisation, self).save(*args, **kwargs) 

也許有更好的方法來生成代碼,但不知道爲什麼它必須是一塊uuid4的。你也可以用你需要的字符集嘗試一個隨機字符串。

+0

他他這正是我自從我發佈這個問題以來:)我的主要問題是我討厭使用,而布魯斯,因爲我們沒有controle,所以我害怕無限的boucles。我想我在這裏沒有選擇,謝謝你的具體答案:) – billyJoe

+0

如果你想要一個獨特的基於時間的ID,你也可以看看'uuid1' –

+0

你可以避免一個無限的while循環與一個大的for循環 – arocks

0

如果你想創建一個獨特的後綴,那麼你可以檢查它是否存在並繼續嘗試,直到您生成不存在的代碼。

def save(self, *args, **kwargs): 
    """ override save method to add specific values """ 
    if self.pk is None: 
     for i in range(100): # Try 100 times to avoid infinite loops 
      code = strftime('%y%m')+str(uuid4())[:4] 
      if not Organisation.objects.filter(code=code): 
       break 
     self.code = code 
    super(Organisation, self).save(*args, **kwargs) 
相關問題