[Django]-Django: timezone.now vs timezone.now()

48πŸ‘

βœ…

In python everything is an object, including functions. This means you can affect a function to a variable:

>>> from django.utils import timezone
>>> foo = timezone.now
>>> foo
<function django.utils.timezone.now>
>>> foo()
datetime.datetime(2016, 7, 7, 9, 11, 6, 489063)

A function is a callable object:

>>> callable(foo)
True
>>> callable(foo())
False

When default receives a callable, the callable is called each time a default value is requested.

On the other hand, when you call timezone.now() prior to setting default, the value is given and fixed. As a reminder, the following line is executed only once at server start up, since it is a class attribute:

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

and thus timezone.now() is executed only once. Passing a callable timezone.now makes it possible to recalculate the value whenever it needs to be.

12πŸ‘

The difference is that timezone.now is a callable that gets executed at runtime, while timezone.now() returns the output of that function.

For the models.DateTimeField, you need to use the callable. Better still, just set auto_now_add which does this for you:

datetime_released = models.DateTimeField(auto_now_add=True)

The filter on the other hand does not accept a callable – it requires a value. Hence you must evaluate timezone.now() when passing this as an argument to the filter.

πŸ‘€solarissmoke

2πŸ‘

In self.filter(date_available__lte = timezone.now()) you want to make a query to the DB based on the current time. So you need it in string format.

In datetime_released = models.DateTimeField(default=timezone.now) you want default to be current time. So you cannot have a string there. Instead you provide a function which can return current time.

πŸ‘€Arun Ghosh

1πŸ‘

now() gets executed when the model is loaded and returns a datetime object / time string at loading. (hence the Django warning!)
(The model file if fully executed when the server starts)

now will pass on the now method, and will get executed only when the class/model gets instantiated, creating the time stamp at the right time (the correct way, and what most people are trying to achieve).

In the filter example, it only gets called when the filter function is called.
if you don’t executed (now()) and will feed the method, and will never generate the required datetime object. (error, expected a string, got, something else)

πŸ‘€gtalarico

1πŸ‘

timezone.now() returns the current timestamp when when model is loaded. On the other hand, timezone.now is passed as an argument to the function and it is called whenever the object is created (on class instantiation)

in the following code

def date_available(self):
    return self.filter(date_available__lte = timezone.now())

the function date_availabe needs a function string to parse as a function when it returns self.filter.

Leave a comment