[Django]-Django datetime issues (default=datetime.now())

765πŸ‘

βœ…

it looks like datetime.now() is being evaluated when the model is defined, and not each time you add a record.

Django has a feature to accomplish what you are trying to do already:

date = models.DateTimeField(auto_now_add=True, blank=True)

or

date = models.DateTimeField(default=datetime.now, blank=True)

The difference between the second example and what you currently have is the lack of parentheses. By passing datetime.now without the parentheses, you are passing the actual function, which will be called each time a record is added. If you pass it datetime.now(), then you are just evaluating the function and passing it the return value.

More information is available at Django’s model field reference

πŸ‘€Carson Myers

198πŸ‘

Instead of using datetime.now you should be really using from django.utils.timezone import now

Reference:

so go for something like this:

from django.utils.timezone import now


created_date = models.DateTimeField(default=now, editable=False)
πŸ‘€andilabs

34πŸ‘

From the documentation on the django model default field:

The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.

Therefore following should work:

date = models.DateTimeField(default=datetime.now,blank=True)
πŸ‘€mykhal

22πŸ‘

David had the right answer. The parenthesis () makes it so that the callable timezone.now() is called every time the model is evaluated. If you remove the () from timezone.now() (or datetime.now(), if using the naive datetime object) to make it just this:

default=timezone.now

Then it will work as you expect:
New objects will receive the current date when they are created, but the date won’t be overridden every time you do manage.py makemigrations/migrate.

I just encountered this. Much thanks to David.

πŸ‘€MicahT

13πŸ‘

The datetime.now() is evaluated when the class is created, not when new record is being added to the database.

To achieve what you want define this field as:

date = models.DateTimeField(auto_now_add=True)

This way the date field will be set to current date for each new record.

πŸ‘€Bartosz

9πŸ‘

datetime.now() is being evaluated once, when your class is instantiated. Try removing the parenthesis so that the function datetime.now is returned and THEN evaluated. I had the same issue with setting default values for my DateTimeFields and wrote up my solution here.

πŸ‘€David

7πŸ‘

From the Python language reference, under Function definitions:

Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that that same β€œpre-computed” value is used for each call.

Fortunately, Django has a way to do what you want, if you use the auto_now argument for the DateTimeField:

date = models.DateTimeField(auto_now=True)

See the Django docs for DateTimeField.

πŸ‘€ars

7πŸ‘

The answer to this one is actually wrong.

Auto filling in the value (auto_now/auto_now_add isn’t the same as default). The default value will actually be what the user sees if its a brand new object. What I typically do is:

date = models.DateTimeField(default=datetime.now, editable=False,)

Make sure, if your trying to represent this in an Admin page, that you list it as β€˜read_only’ and reference the field name

read_only = 'date'

Again, I do this since my default value isn’t typically editable, and Admin pages ignore non-editables unless specified otherwise. There is certainly a difference however between setting a default value and implementing the auto_add which is key here. Test it out!

πŸ‘€Andrew Harris

3πŸ‘

In Django 3.0 auto_now_add seems to work with auto_now

reg_date=models.DateField(auto_now=True,blank=True)

πŸ‘€Bosco Oludhe

3πŸ‘

if you need only DateField try this

date = models.DateField(auto_now=False, auto_now_add=False, null=True, blank=True)

if you need Both Date and Time try this

date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
πŸ‘€Manoj Parmar

Leave a comment