Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UUID as default value in Django model

I've noticed the strange behaviour of default value in django model. For example we have a simple django model:

import uuid
...

class SiteUser(models.Model):
    ...
    username = models.CharField(max_length=255, verbose_name=u"Username")
    activation_key = models.CharField(max_length=64, verbose_name=u"Activation key", default=uuid.uuid1())

When I create a new user, and after that another one like that:

user_a = SiteUser(username="UserA")
user_a.save()
user_b = SiteUser(username="UserB")
user_b.save()

Django makes 2 users with the same activation_key

But then I do it like that:

user_a = SiteUser(username="UserA")
user_a.activation_key = uuid.uuid1()
user_a.save()
user_b = SiteUser(username="UserB")
user_b.activation_key = uuid.uuid1()
user_b.save()

Everything works fine and Django creates 2 users with different activation keys.

What's going on here? Python loads model object and calculate the default value of the model when the wsgi app starts up or that? Why uuid gives the same values in the first case but different in second?

Thanks.

like image 512
Dmitry Astrikov Avatar asked Sep 14 '14 15:09

Dmitry Astrikov


2 Answers

Problem is the default attribute that you are setting as

activation_key = models.CharField(max_length=64, verbose_name=u"Activation key",
                 default=uuid.uuid1())

Here you are setting the default value as not a callable but value returned by uuid.uuid1() call when this model class is initialized.

You should set it as default=uuid.uuid1 which sets it as callable, and is sets new uuid each time new default value needs to be used.

like image 156
Rohan Avatar answered Sep 21 '22 00:09

Rohan


As of Django 1.8, there is a new UUIDField available. It's described in the following link which also covers how to set defaults:

https://docs.djangoproject.com/en/1.8/ref/models/fields/#uuidfield

like image 24
ozren1983 Avatar answered Sep 20 '22 00:09

ozren1983