Django:timezone.now vs timezone.now()

43T*_*cts 16 python django timezone

我正在将我的项目从Django 1.8.2升级到1.9.7,我收到了这个警告:

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
Run Code Online (Sandbox Code Playgroud)

这是my_app/models.py中的行:

from django.utils import timezone
...
class my_model(models.Model):
    ...
    datetime_released = models.DateTimeField(default=timezone.now() )
Run Code Online (Sandbox Code Playgroud)

如果我删除括号而改为使用:

datetime_released = models.DateTimeField(default=timezone.now )
Run Code Online (Sandbox Code Playgroud)

Django警告消失了.这两者有什么区别?


在我的项目的另一个领域,我在queryset过滤器中使用timezone.now():

def date_available(self):
        return self.filter(date_available__lte = timezone.now())
Run Code Online (Sandbox Code Playgroud)

在这里,如果删除括号,则会抛出错误:

TypeError: expected string or buffer


我可以通过添加/删除所需的括号内同时获得这两项工作,但之间有什么区别timezone.now()timezone.now,为什么他们会在这些情况下警告/错误?

Ant*_*ard 23

在python中,一切都是对象,包括函数.这意味着您可以影响变量的函数:

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

函数是可调用对象:

>>> callable(foo)
True
>>> callable(foo())
False
Run Code Online (Sandbox Code Playgroud)

default接收到可调用对象时,每次请求默认值时都会调用可调用对象.

另一方面,当您timezone.now()在设置之前调用时default,将给出并修复该值.提醒一下,以下行只在服务器启动时执行一次,因为它是一个类属性:

    datetime_released = models.DateTimeField(default=timezone.now())
Run Code Online (Sandbox Code Playgroud)

因此timezone.now()只执行一次.传递callable timezone.now可以在需要时重新计算值.


sol*_*oke 10

区别在于它timezone.now是在运行时执行的可调用,同时timezone.now()返回该函数的输出.

对于models.DateTimeField,您需要使用callable.更好的是,只需设置auto_now_add为您执行此操作:

datetime_released = models.DateTimeField(auto_now_add=True)
Run Code Online (Sandbox Code Playgroud)

另一方面,过滤器不接受可调用 - 它需要一个值.因此,您必须timezone.now()在将此作为参数传递给过滤器时进行评估.