对于Django 1.1。
我在我的models.py中有这个:
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
当更新一行时,我得到:
[Sun Nov 15 02:18:12 2009] [error] /home/ptarjan/projects/twitter-meme/django/db/backends/mysql/base.py:84: Warning: Column 'created' cannot be null
[Sun Nov 15 02:18:12 2009] [error] return self.cursor.execute(query, args)
我的数据库的相关部分是:
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
这值得关注吗?
小问题:在我的管理工具中,这两个字段没有显示。这是意料之中的吗?
根据我所读到的和我目前使用Django的经验,auto_now_add是有bug的。我同意jthanism,重写正常的保存方法,这很干净,你知道发生了什么。现在,为了使它变干,创建一个名为TimeStamped的抽象模型:
from django.utils import timezone
class TimeStamped(models.Model):
creation_date = models.DateTimeField(editable=False)
last_modified = models.DateTimeField(editable=False)
def save(self, *args, **kwargs):
if not self.creation_date:
self.creation_date = timezone.now()
self.last_modified = timezone.now()
return super(TimeStamped, self).save(*args, **kwargs)
class Meta:
abstract = True
然后,当你想要一个具有这种时间戳行为的模型时,只需子类:
MyNewTimeStampyModel(TimeStamped):
field1 = ...
如果您希望字段显示在管理中,那么只需删除editable=False选项
这值得关注吗?
不,在保存模型时,Django会自动为你添加它,所以,这是意料之中的。
辅助问题:在我的管理工具中,这两个字段没有显示。这是意料之中的吗?
由于这些字段是自动添加的,所以不会显示它们。
为了补充上面的内容,正如synack所说,django邮件列表中一直有关于删除它的争论,因为它“设计得不好”,是“一个黑客”。
在我的每个模型上编写自定义save()比使用auto_now要痛苦得多
显然,你不需要对每个模型都写。您可以将它写入一个模型,并从它继承其他模型。
但是,由于存在auto_add和auto_now_add,我宁愿使用它们,而不是自己尝试编写方法。
我今天工作也需要类似的东西。默认值是时区.now(),但可编辑的管理和类视图继承自FormMixin,所以创建在我的models.py下面的代码满足这些要求:
from __future__ import unicode_literals
import datetime
from django.db import models
from django.utils.functional import lazy
from django.utils.timezone import localtime, now
def get_timezone_aware_now_date():
return localtime(now()).date()
class TestDate(models.Model):
created = models.DateField(default=lazy(
get_timezone_aware_now_date, datetime.date)()
)
对于DateTimeField,我想从函数中删除.date()并更改datetime。日期到日期时间。Datetime或者更好的timezone.datetime。我没有在DateTime上尝试过,只在Date上尝试过。
根据我所读到的和我目前使用Django的经验,auto_now_add是有bug的。我同意jthanism,重写正常的保存方法,这很干净,你知道发生了什么。现在,为了使它变干,创建一个名为TimeStamped的抽象模型:
from django.utils import timezone
class TimeStamped(models.Model):
creation_date = models.DateTimeField(editable=False)
last_modified = models.DateTimeField(editable=False)
def save(self, *args, **kwargs):
if not self.creation_date:
self.creation_date = timezone.now()
self.last_modified = timezone.now()
return super(TimeStamped, self).save(*args, **kwargs)
class Meta:
abstract = True
然后,当你想要一个具有这种时间戳行为的模型时,只需子类:
MyNewTimeStampyModel(TimeStamped):
field1 = ...
如果您希望字段显示在管理中,那么只需删除editable=False选项