2014-02-19 3 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) 

Как вы можете себе представить, этот код не работает, это плохой код, но я не знаю, как это сделать: '( EDIT: формат кода является ограничением, я не могу его изменить

ответ

1

Как я undestand это вы получаете 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

он это именно то, что я сделал с тех пор, как я разместил этот вопрос :) Моя основная проблема - я ненавижу использование в то время как на велосипедах, потому что у нас нет контроля, так что я боюсь бесконечных боев. Я думаю, у меня нет выбора здесь, спасибо за ваш конкретный ответ :) – billyJoe

+0

Если вы хотите уникальный идентификатор, основанный на времени, вы также можете посмотреть 'uuid1' –

+0

Вы можете избежать бесконечного цикла while с большим циклом цикла – 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) 
Смежные вопросы