升级到 Django 1.8 后“提供的固定默认值”

Posted

技术标签:

【中文标题】升级到 Django 1.8 后“提供的固定默认值”【英文标题】:"Fixed default value provided" after upgrading to Django 1.8 【发布时间】:2015-06-15 11:23:44 【问题描述】:

Django 1.8 现在对模型进行了一些问题检测,这很好。但是,对于它给我的一个警告,我理解这个问题,但我不明白它给我的提示如何更好。

这是我的(坏)模型字段:

my_date = DateField(default=datetime.now())

很容易看出为什么不好。但这是它给我的提示:

MyMoel.my_date:(fields.W161) 提供固定默认值。 提示:您似乎为此字段设置了一个固定的日期/时间/日期时间值作为默认值。这可能不是你想要的。如果您想将当前日期设为默认值,请使用 `django.utils.timezone.now`

所以,它说要使用timezone.now,但它怎么比datetime.now 好?它们都是“固定默认”值...timezone.now 只是返回一个日期时间实例,它是一个固定值...

我怀疑它实际上是想让我插入某种标记,上面写着“使用timezone.now稍后”。但这不是提示所说的......那么那个标志是什么?

【问题讨论】:

【参考方案1】:

函数datetime.now() 当前在您的代码被导入后立即执行,即当您(重新)启动服务器时。所有后续模型实例都将具有相同的值。

相反,您应该将可调用函数传递给default,每次模型实例需要默认值时都会执行该函数。提示想要传达您应该直接使用 DateField(default=django.utils.timezone.now) 而不带括号。

该消息有点误导,但 Django 不知道您使用的是datetime.now() 还是django.utils.timezone.now()

【讨论】:

所以给它任何可调用的东西都会让验证器高兴(即我可以传递它datetime.nowtimezone.now,或者任何返回日期的函数)? 是的,它们中的任何一个都应该让验证者(最终是你)感到高兴。【参考方案2】:

timezone.now()datetime.now() 之间的区别已在上述答案中得到很好的解释。 但是,您收到错误的原因是您正在运行将默认时间设置为将迁移应用到数据库时的时间的函数。

你所要做的就是使用,

my_date = DateField(default=datetime.now)

而不是

my_date = DateField(default=datetime.now())

在上述方法中,timezone.now函数将在插入/修改对象时被调用。

【讨论】:

【参考方案3】:

完全同意@knbk

在我的实现中,我首先进行了导入

我的模型.py:

from django.utils import timezone

然后,在创建模型时,我这样做了:

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

所以总代码是:

from django.db import models
from django.utils import timezone
from django.urls import reverse

# Create your models here.

class Post(models.Model):
    author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    text = models.TextField()
    create_date = models.DateTimeField(default=timezone.now)
    published_date = models.DateTimeField(blank=True,null=True)

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def approve_comments(self):
        return self.comments.filter(approve_comments=True)

    def __str__(self):
        return self.title

【讨论】:

以上是关于升级到 Django 1.8 后“提供的固定默认值”的主要内容,如果未能解决你的问题,请参考以下文章

升级到 1.8 后进行迁移时出现 DjangoUnicodeDecodeError

我无法从 Django 1.8 升级到 2.0

从 1.8 升级到 1.9 Django Admin get_urls 不起作用

从 Django 1.6 (with south) 升级到 1.8 不会修改用户表上的“last_login”

无法将 Django 从 1.7 迁移到 1.8

Django 1.8 和鼻子:冲突的模型?