Lucas Ou-Yang
Lucas Ou-Yang

Reputation: 5655

Django "default=timezone.now()" saves records using the "old" time of when the Django server starts

This issue has been occurring on and off for a few weeks now, and it's unlike any that has come up with my project.

Two of the models that are used have a timestamp field, which is by default set to timezone.now().

This is the sequence that raises error flags:


Every model that is created has its time stamp saved under 7:30 PM, not the actual time, until a certain duration passes. Then a new time is set and all the following models have that new time... Bizzare


Some extra details which may help in discovering the issue:

I have a bunch of methods that I use to strip my timezones of their tzinfo's and replace them with UTC.

This is because I'm doing a timezone.now() - creationTime calculation to create a: "model was posted this long ago" feature in the project. However, this really should not be the cause of the problem.

I don't think using datetime.datetime.now() will make any difference either.

Anyway, thanks for the help!

Upvotes: 29

Views: 32507

Answers (3)

You should set timezone.now without () to DateTimeField() as a default value as shown below. *Don't set timezone.now() with () because the default date and time become when the Django server starts (Unchanged) and don't set datetime.now because UTC is not saved correctly in database when TIME_ZONE = 'UTC' which is default in settings.py:

from django.utils import timezone
# Don't set "timezone.now()" and "datetime.now" ↓ 
timestamp = models.DateTimeField(default=timezone.now)

Upvotes: 2

Rag Sagar
Rag Sagar

Reputation: 2374

Just set the parameter auto_now_add like this.

timestamp = models.DateTimeField(auto_now_add=True)

Update:

Please don't use auto_now_add. It is not the recommended way, instead do this:

from django.utils import timezone

timestamp = models.DateTimeField(default=timezone.now)

Upvotes: 25

Jamey Sharp
Jamey Sharp

Reputation: 8511

Just ran into this last week for a field that had default=date.today(). If you remove the parentheses (in this case, try default=timezone.now) then you're passing a callable to the model and it will be called each time a new instance is saved. With the parentheses, it's only being called once when models.py loads.

Upvotes: 72

Related Questions