开发者

Why does Django get_or_create cause this IntegrityError?

I have a model that has this field on it:

token = models.CharField(max_length=32, default="", unique=True, null=False, db_index=True)

In the save() method I set this field to a 32 character random string using this method:

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开发者_JAVA技巧.digits) for x in range(n))

However I am getting this error whenever I try to create a new instance of the model:

IntegrityError: duplicate key value violates unique constraint "wakelytics_sessionpassthrough_token_key"

To create the instance I call this method:

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

Does get_or_create() call the method's save() function before writing to the database? Answer: Yes

I get an IntegrityError whenever I call the method for the first time with a session, and continue getting the error for a few minutes. It then returns correctly. What is causing this?


Yes.

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

From the docs:

The new object will be created roughly according to this algorithm:

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()


Of course it does. Part of its contract is that it will return a model that does exist, and in order to do that it has to save.

EDIT:

You're getting that error because the value already exists in the database.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜