将模型重新保存到try catch中

时间:2014-02-19 09:24:42

标签: django django-models

这是一个设计问题。

假设一个具有名称和代码的组织

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)

你可以想象,这段代码不起作用,这是一个糟糕的代码,但我不知道该怎么做:'( 编辑:代码格式是一个约束,我无法改变它

2 个答案:

答案 0 :(得分: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的一部分。您也可以尝试使用您需要的字符集的随机字符串。

答案 1 :(得分: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)