I am in the process of upgrading my project from Django 1.8.2 to 1.9.7 and I'm getting this warning:
WARNINGS: my_app.my_model.date_available: (fields.W161) Fixed default value provided. HINT: It seems you set a fixed date / time / datetime value as default for this field. This may not be what you want. If you want to have the current date as default, use `django.utils.timezone.now
Here's the line from my_app/models.py:
from django.utils import timezone ... class my_model(models.Model): ... datetime_released = models.DateTimeField(default=timezone.now() )
If I remove the parentheses and instead use:
datetime_released = models.DateTimeField(default=timezone.now )
The Django warning goes away. What's the difference between the two?
In another area of my project I am using timezone.now() in a queryset filter:
def date_available(self): return self.filter(date_available__lte = timezone.now())
Here, if I remove the parentheses, an error is thrown:
TypeError: expected string or buffer
I can get both of these two work by adding/removing the parenthesis as required, but what is the difference between timezone.now()
and timezone.now
and why do they cause warnings/errors in these cases?
timezone. now() useful. This function returns the current date and time as a naive datetime when USE_TZ = False and as an aware datetime when USE_TZ = True .
In the documentation, it can also be seen that, since Python 3.6, datetime. now() can be called without any arguments and return the correct local result (naive datetime s are presumed to be in the local time zone).
Django's timezone is set to UTC by default. If your timezone is not UTC, you can change it using the procedure below: Open the setting.py file in the directory of our project.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With