模型中的 Django default=datetime.now() 在 uwsgi 重置后总是保存相同的日期时间

Posted

技术标签:

【中文标题】模型中的 Django default=datetime.now() 在 uwsgi 重置后总是保存相同的日期时间【英文标题】:Django default=datetime.now() in models always saves same datetime after uwsgi reset 【发布时间】:2015-06-26 07:29:03 【问题描述】:

我的模型中有这段代码:

added_time = models.DateTimeField(
    default=datetime.datetime.now()
)

迁移并重新启动 uwsgi 后,我现在在 MariaDB 中获得了第一个日期时间,接下来都是 - 与重置 uwsgi 后的第一个日期时间完全相同。

2015-04-19 16:01:46
2015-04-19 16:01:46
2015-04-19 16:01:46
2015-04-19 16:01:46

我通过将代码更改为:

added_time = models.DateTimeField(
    auto_now_add=True
)

虽然我解决了问题,但我不确定为什么会有这样的行为?

【问题讨论】:

我对 Django 了解不多,但我的钱是在 default 被评估一次,当类被评估时。它也发生在函数的关键字参数上。尝试:def foo(argument=datetime.datetime.now()): print argument,然后使用while 循环或其他东西对其进行测试:while True: foo() 你会看到argument 没有改变 Django. default=datetime.now() problem的可能重复 如果您在这里是因为datetime.now 没有在您的班级默认值中进行评估,请在此处查看我的帖子:dhariri.com/posts/56f68c45d1befa569505cf0f 【参考方案1】:

default=datetime.datetime.now() 在模型的解析/编译时进行评估。之后不会更改。要在添加/更新对象时评估 now(),您必须使用:

default=datetime.datetime.now,将now 设置为可调用对象。 Django 会在运行时调用它。

您使用auto_now_add 的解决方案当然也是正确的(但在语义上有所不同——传递默认值将在每次保存模型时设置值,而auto_now_add 只在创建时执行一次)。

不要失望,这是一个非常 common 的错误。

【讨论】:

也谢谢您,好心的先生!你不仅拯救了我的一天,而且用 python gotchas 展示了精彩的网站 在你的最后一段中,你链接到一个解释函数的默认参数如何可变和持久的网站。这是一个完全不同的问题,然后是这个问题帖子中的问题:在 Python 中,example 给出函数,而example() 调用函数并给出返回值,不像 Perl,其中 @987654330 @ 和example() 是等价的,&example 是检索函数引用的方式。 是的,我同意这些实际上是不同的情况。然而,这是相同的根本原因——参数是在编译时评估的,而不是像第一眼看到的那样在运行时评估。【参考方案2】:

您需要将datetime.datetime.now 而不是datetime.datetime.now() 传递给默认值。否则,在初始化模型时会计算默认值,因此在重新启动后始终会得到相同的值。

请参阅 Django documentation 以获得更详尽的说明。

如果使用 Django 的时区支持,请记住使用 django.utils.timezone.now 而不是 datetime.datetime.now

【讨论】:

以上是关于模型中的 Django default=datetime.now() 在 uwsgi 重置后总是保存相同的日期时间的主要内容,如果未能解决你的问题,请参考以下文章

如何在django中的模型中定义日期格式?

带有查找字段的嵌套模型外键上的 Django JOIN

DateTable转化为泛型集合

使用继承类中的字段的 Django 模型约束条件 - 可能吗?

Django(博客系统):按照时间分层筛选“/blog/article/?create_time__year=2017”,出现问题:Database returned an invalid datet

django QuerySet 过滤器()