Django:timezone.now 与 timezone.now()

新手上路,请多包涵

我正在将我的项目从 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

这是来自 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


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

原文由 43Tesseracts 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

在 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 可以在需要时重新计算值。

原文由 Antoine Pinsard 发布,翻译遵循 CC BY-SA 3.0 许可协议

不同之处在于 timezone.now 是在运行时执行的可调用对象,而 timezone.now() 返回该函数的输出。

对于 models.DateTimeField ,您需要使用可调用对象。更好的是,只需设置 auto_now_add 为您完成此操作:

 datetime_released = models.DateTimeField(auto_now_add=True)

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

原文由 solarissmoke 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏