Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django default=datetime.now() in models always saves same datetime after uwsgi reset

I have this code in my model:

added_time = models.DateTimeField(
    default=datetime.datetime.now()
)

After I migrate and restart uwsgi, I get first datetime in MariaDB now, and all next - exactly the same as first after resetting uwsgi.

2015-04-19 16:01:46
2015-04-19 16:01:46
2015-04-19 16:01:46
2015-04-19 16:01:46

I fixed it by changing code to:

added_time = models.DateTimeField(
    auto_now_add=True
)

Though I fixed the problem, I'm not really sure why there even was such behavior?

like image 241
idchlife Avatar asked Apr 19 '15 17:04

idchlife


2 Answers

default=datetime.datetime.now() is evaluated at parsing/compile time of the model. It is not changed afterwards. To evaluate now() at the time of adding/updating an object, you have to use:

default=datetime.datetime.now, which sets now as the callable. Django will call it at runtime.

Your solution of using auto_now_add is of course also correct (yet semantically different -- passing a default will set the value every time the model is saved, whereas auto_now_add only does it once, at creation time).

Don't dispair, this is avery common mistake.

like image 65
miraculixx Avatar answered Nov 15 '22 20:11

miraculixx


You need to pass datetime.datetime.now instead of datetime.datetime.now() to default. Otherwise, the default value is computed when the model is initialized hence you always get the same value after a restart.

See the Django documentation for a more thorough explanation.

If using Django's time zones support, remember to use django.utils.timezone.now instead of datetime.datetime.now.

like image 36
aumo Avatar answered Nov 15 '22 18:11

aumo