我有以下数据库模型:
from datetime import datetime
class TermPayment(models.Model):
# I have excluded fields that are irrelevant to the question
date = models.DateTimeField(default=datetime.now(), blank=True)
我使用以下内容添加了一个新实例:
tp = TermPayment.objects.create(**kwargs)
我的问题:数据库中的所有记录在日期字段中具有相同的值,即第一次付款的日期。服务器重新启动后,一条记录具有新日期,其他记录与第一条记录相同。看起来好像有些数据被缓存了,但我找不到在哪里。
数据库:mysql 5.1.25
django v1.1.1
default=datetime.now
- 注意,没有像 now()
中那样调用不是 DateTimeField 的标准,但是......无论如何都很方便。
似乎在定义模型时正在评估 datetime.now()
,而不是每次添加记录时。
Django 有一个功能可以完成您已经尝试做的事情:
date = models.DateTimeField(auto_now_add=True, blank=True)
或者
date = models.DateTimeField(default=datetime.now, blank=True)
第二个示例与您当前拥有的示例之间的区别在于缺少括号。通过传递不带括号的 datetime.now
,您传递的是实际函数,每次添加记录时都会调用该函数。如果您传递它 datetime.now()
,那么您只是在评估函数并将返回值传递给它。
更多信息可在 Django 的 model field reference
您应该真正使用 from django.utils.timezone import now
而不是使用 datetime.now
参考:
django.utils.timezone.now 的文档
所以去做这样的事情:
from django.utils.timezone import now
created_date = models.DateTimeField(default=now, editable=False)
auto_now_add
(可识别时区)加时间戳的字段进行比较,您可能会因为错误的时区差异而得到错误的计算。
从 django 模型默认字段的 documentation 中:
字段的默认值。这可以是一个值或可调用对象。如果可调用,则每次创建新对象时都会调用它。
因此以下应该工作:
date = models.DateTimeField(default=datetime.now,blank=True)
default
(django-chinese-docs-14.readthedocs.io/en/latest/ref/models/…)
AttributeError: module 'datetime' has no attribute 'now'
。使用 default=datetime.datetime.now
修复它
大卫有正确的答案。括号 () 使得每次评估模型时都会调用可调用的 timezone.now()。如果您从 timezone.now() (或 datetime.now(),如果使用天真 datetime 对象)中删除 () 使其成为这样:
default=timezone.now
然后它将按您的预期工作:新对象将在创建时收到当前日期,但每次执行 manage.py makemigrations/migrate 时都不会覆盖该日期。
我刚遇到这个。非常感谢大卫。
datetime.now()
在创建类时评估,而不是在将新记录添加到数据库时评估。
为了实现你想要的定义这个字段:
date = models.DateTimeField(auto_now_add=True)
这样,date
字段将设置为每条新记录的当前日期。
datetime.now()
在您的类被实例化时被评估一次。尝试删除括号,以便返回函数 datetime.now
并对其进行评估。我在为我的 DateTimeField
设置默认值时遇到了同样的问题,并写了我的解决方案 here。
在 Python 语言参考的 Function definitions 下:
执行函数定义时评估默认参数值。这意味着在定义函数时对表达式进行一次评估,并且每次调用都使用相同的“预计算”值。
幸运的是,如果您对 DateTimeField
使用 auto_now
参数,Django 有办法做您想做的事:
date = models.DateTimeField(auto_now=True)
请参阅 DateTimeField 的 Django 文档。
这个问题的答案实际上是错误的。
自动填写值(auto_now/auto_now_add 与默认值不同)。如果它是一个全新的对象,默认值实际上就是用户所看到的。我通常做的是:
date = models.DateTimeField(default=datetime.now, editable=False,)
如果您尝试在管理页面中表示此内容,请确保将其列为“只读”并引用字段名称
read_only = 'date'
同样,我这样做是因为我的默认值通常不可编辑,并且除非另有说明,否则管理页面会忽略不可编辑的内容。然而,在设置默认值和实现这里的关键 auto_add 之间肯定有区别。测试一下!
在 Django 3.0 中,auto_now_add
似乎与 auto_now
一起使用
reg_date=models.DateField(auto_now=True,blank=True)
如果你只需要 DateField 试试这个
date = models.DateField(auto_now=False, auto_now_add=False, null=True, blank=True)
如果你需要日期和时间试试这个
date = models.DateTimeField(auto_now_add=True, null=True, blank=True)
不定期副业成功案例分享
expiry = models.DateTimeField(default=datetime.now + timedelta(days=30))
def now_plus_30(): return datetime.now() + timedelta(days = 30)
,然后使用models.DateTimeField(default=now_plus_30)
default=lambda: datetime.now()+timedelta(days=30)