2016-07-07 29 views
5

我在从Django的1.8.2我的项目升级到1.9.7的过程中,我得到这样的警告:Django的:timezone.now VS timezone.now()

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 

这里的行从程序my_app/models.py:

from django.utils import timezone 
... 
class my_model(models.Model): 
    ... 
    datetime_released = models.DateTimeField(default=timezone.now()) 

如果我删除了括号,而使用:

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

Django的警告消失。两者有什么区别?


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

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

在这里,如果我删除括号,抛出一个错误:

TypeError: expected string or buffer


我可以通过根据需要添加/删除括号来获得这两项工作d,但timezone.now()timezone.now之间的区别是什么以及它们在这些情况下为什么会导致警告/错误?

+0

类型(now())重新运行日期时间对象。现在重新运行该方法 – gtalarico

回答

9

在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) 

函数是一个可调用对象:

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

default接收一个可调用的,可调用每次请求一个缺省值时间被调用。

另一方面,当您在设置default之前拨打timezone.now()时,该值将被给定并固定。作为提醒,下面的行执行只能在服务器一次启动时,因为它是一个类属性:

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

因此timezone.now()只执行一次。通过可调用timezone.now可以在需要时重新计算值。

8

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

对于models.DateTimeField,您需要使用可调用函数。更妙的是,刚刚成立auto_now_add它可以实现这个要求:

datetime_released = models.DateTimeField(auto_now_add=True) 

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

+0

这里值得一提的是,当你传递'timezone.now()'时,你在django启动时有效地传递了该函数的输出(这是它得到评估),而当你传递'timezone.now'时,你传递的是被django懒散评估的函数对象。 – samu

1

now()在模型加载时得到执行,并在加载时返回一个datetime对象/时间字符串。 (因此Django的警告!) (模型文件,如果完全执行了服务器启动时)

现在将通过现在的方法,只有当类/模型被实例化将得到执行,在创建时间戳正确的时间(正确的方式,以及大多数人试图达到的目标)。

在过滤器示例中,仅在调用过滤器函数时才会调用它。 如果你没有执行(now())并且会提供方法,并且永远不会生成所需的datetime对象。 (错误,期望一个字符串,得到,别的东西)

1

self.filter(date_available__lte = timezone.now())你想根据当前时间查询数据库。所以你需要它的字符串格式。

datetime_released = models.DateTimeField(default=timezone.now)您要默认为当前时间。所以你不能在那里有一个字符串。而是提供可以返回当前时间的功能。

相关问题