为什么Django get_or_create导致此IntegrityError?

时间:2011-06-16 01:58:36

标签: python django orm model

我有一个模型,上面有这个字段:
token = models.CharField(max_length=32, default="", unique=True, null=False, db_index=True)

在save()方法中,我使用此方法将此字段设置为32个字符的随机字符串:

def save(self, *args, **kwargs):
    if (self.token is None or len(self.token) == 0):
        self.token = random_identifier()
    super(SessionPassthrough, self).save(*args, **kwargs)

def random_identifier(n=32):
    """ Generate a random identifier of length n. 

    From http://stackoverflow.com/questions/2257441/python-random-string-generation-with-upper-case-letters-and-digits"""
    return ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(n))

但是每当我尝试创建模型的新实例时,我都会收到此错误:
IntegrityError: duplicate key value violates unique constraint "wakelytics_sessionpassthrough_token_key"

要创建实例,我调用此方法:

@staticmethod
def for_session(session):
    sp, c = SessionPassthrough.objects.get_or_create(session=session)
    return sp

get_or_create()在写入数据库之前是否调用方法的save()函数? 答案:是

每当我第一次使用session调用该方法时,我会收到IntegrityError,并继续收到错误几分钟。然后它正确返回。造成这种情况的原因是什么?

2 个答案:

答案 0 :(得分:3)

https://docs.djangoproject.com/en/dev/ref/models/querysets/#get-or-create

来自文档:

将根据此算法大致创建新对象:

defaults = kwargs.pop('defaults', {})
params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
params.update(defaults)
obj = self.model(**params)
obj.save()

答案 1 :(得分:1)

当然可以。它的部分合同是返回 存在的模型,为了做到这一点,它必须保存。

修改

您收到该错误,因为该值已存在于数据库中。