Not to say that this is a bug in django but rather a bug in how I had written some of my models.
Just wanted to point out a quick tip for anyone else who may have done the same thing as me as well as for any of the django experts out there that might suggest a better way.
What was happening was that I began to notice a wild discreptancy between two datetime columns in several models. They should have been identical, however, they were both getting their dates differently:
...
date_column_one = models.DateTimeField(default=datetime.now())
date_column_two = models.DateTimeField(auto_now_add=True)
...
What seems to be happening with this configuration is that datetime.now() is executed once when the server starts (and/or the module is imported) instead of what I thought would happen when I initially wrote these and that datetime.now() would get executed anytime an instance of the model was created and saved as a new record.
My solution was to override the save method:
...
date_column_one = models.DateTimeField()
...
def save(self):
if not self.id:
self.date_column_one = datetime.now()
super(MyModel, self).save()
...
I am sure there is probably a better way and if you know of one, please leave a comment or send me an email and let me know!












19 comments ↓
Try
models.DateTimeField(default=datetime.now)Django will execute the function in the way I think you expect.
You can do it like so: models.DateTimeField(default=datetime.now)
You should use the callable:
datecolumnone = models.DateTimeField(default=datetime.now)
datecolumnone = models.DateTimeField(default=datetime.datetime.now)
Pass the function, not call it.
Hi, uses
models.DateTimeField(default=datetime.now)… without parenthesis…You need to pass “default” a callable if you want it to be called every time a new object is being created:
http://www.djangoproject.com/documentation/model-api/#default
In the sample code above, you’re passing it a datetime.datetime object, as you’re actually calling the datetime.now() method instead of just passing a reference to it:
datecolumnone = models.DateTimeField(default=datetime.now)
Just use the callable instead (no ending parenthesis). e.g…
datecolumnone = models.DateTimeField(default=datetime.now)
It’s a common mistake particularly because you’re not likely to notice it when running the dev server.
Try not to use autonowadd, it’s deprecated or will be soon.
I’ve been tripped up by similar behavior. What you probably want is to pass the callable to the default argument rather than the result of the callable; see:
http://www.djangoproject.com/documentation/models/field_defaults/
The easiest way to do it is like so: datecolumnone = models.DateTimeField(default=datetime.now)
Reason being, you can pass a callable for the default value that will be evaluated upon save. In this case, the callable results in the current date and you get what you want.
Maybe you are looking for models.DateTimeField(auto_now = True) ?
http://www.djangoproject.com/documentation/model-api/#datetimefield
Default can be given a callable, so you can do, default=datetime.now
and it will be called at save time.
The ‘default’ argument to any field can be a callable. If you use “default=datetime.now” (note the lack of () at the end), it will call it as a function to get the time when a record is created, rather than evaluating it when the module is imported as you are doing now. (This is in the model_api docs page)
Try passing “default=datetime.now” leaving off the parens will pass the function, and it’ll be called everytime.
LOL, 13 comments (including mine) saying the same thing. Boo for comment moderation!
Oh! Easy! Simply pass a callable rather than an actual value!
default=datetime.now
Sounds good everyone! Thanks for the quick feedback.
hehe, this solves my problem too! thanks
This is one of two classic blunders with default arguments in Python. I’ve written them up because I’m so glad to find out you can pass callables to default= in Django fields. I’d never have known if I hadn’t stumbled across your tweet. Thanks!
http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/
You can do it datecolumnone = models.DateTimeField(autonowadd = true)
Leave a Comment