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.
- [Django]-Django user profile
- [Django]-How to get request object in django unit testing?
- [Django]-Can I access constants in settings.py from templates in Django?
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.
- [Django]-Django get a random object
- [Django]-Prepopulate Django (non-Model) Form
- [Django]-What is the difference between cached_property in Django vs. Python's functools?
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)
- [Django]-How to get the value of a Django Model Field object
- [Django]-Django get_or_create fails to set field when used with iexact
- [Django]-Django Rest Framework with ChoiceField
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.
- [Django]-Connect to a DB using psycopg2 without password
- [Django]-Django access the length of a list within a template
- [Django]-Django, after upgrade: MySQL server has gone away