我有以下数据库模型:
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
答案 0 :(得分:518)
在定义模型时,似乎正在评估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
获得答案 1 :(得分:83)
您应该真正使用datetime.now
from django.utils.timezone import now
所以请选择以下内容:
from django.utils.timezone import now
created_date = models.DateTimeField(default=now, editable=False)
答案 2 :(得分:26)
来自django模型默认字段的documentation:
字段的默认值。这可以是值或可调用对象。如果可调用,则每次创建新对象时都会调用它。
因此,以下应该有效:
date = models.DateTimeField(default=datetime.now,blank=True)
答案 3 :(得分:16)
default=timezone.now
然后它将按预期工作:
新对象将在创建时收到当前日期,但每次执行manage.py makemigrations / migrate时都不会覆盖日期。
我刚刚遇到这个。非常感谢大卫。
答案 4 :(得分:9)
在创建类时评估datetime.now()
,而不是在将新记录添加到数据库时评估。{/ p>
要实现您想要的目标,请将此字段定义为:
date = models.DateTimeField(auto_now_add=True)
这样,date
字段将设置为每个新记录的当前日期。
答案 5 :(得分:6)
datetime.now()
被评估一次。尝试删除括号,以便返回函数datetime.now
并进行评估。我在为DateTimeField
设置默认值时遇到了同样的问题,并写了我的解决方案here。
答案 6 :(得分:6)
这个问题的答案实际上是错误的。
自动填充值(auto_now / auto_now_add与默认值不同)。默认值实际上是用户看到的全新对象。我通常做的是:
date = models.DateTimeField(default=datetime.now, editable=False,)
如果您尝试在管理员页面中表示此内容,请确保将其列为“read_only”并引用字段名称
read_only = 'date'
同样,我这样做是因为我的默认值通常不可编辑,管理页面会忽略不可编辑的内容,除非另有说明。然而,在设置默认值和实现auto_add之间肯定存在差异,这是关键。测试一下!
答案 7 :(得分:5)
从Python语言参考,Function definitions下:
执行函数定义时,将评估默认参数值。这意味着在定义函数时,表达式将被计算一次,并且每次调用都使用相同的“预先计算”值。
幸运的是,如果对auto_now
使用DateTimeField
参数,Django可以做你想要的事情:
date = models.DateTimeField(auto_now=True)
请参阅Django文档DateTimeField。
答案 8 :(得分:0)
在Django 3.0中,auto_now_add
可以与auto_now
一起使用
reg_date=models.DateField(auto_now=True,blank=True)
答案 9 :(得分:0)
如果你只需要 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)