对于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,
这值得关注吗?
小问题:在我的管理工具中,这两个字段没有显示。这是意料之中的吗?
我今天工作也需要类似的东西。默认值是时区.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上尝试过。
auto_now=True在Django 1.4.1中并不适用,但是下面的代码拯救了我。它用于时区感知datetime。
from django.utils.timezone import get_current_timezone
from datetime import datetime
class EntryVote(models.Model):
voted_on = models.DateTimeField(auto_now=True)
def save(self, *args, **kwargs):
self.voted_on = datetime.now().replace(tzinfo=get_current_timezone())
super(EntryVote, self).save(*args, **kwargs)
但我想指出,公认答案中所表达的观点有些过时。根据最近的讨论(django bug #7634和#12785),auto_now和auto_now_add不会消失,即使你去看最初的讨论,你也会在自定义保存方法中发现强烈的反对RY(如DRY)的论点。
已经提供了一个更好的解决方案(自定义字段类型),但还没有获得足够的动力将其纳入django。你可以用三行写你自己的(这是Jacob Kaplan-Moss的建议)。
from django.db import models
from django.utils import timezone
class AutoDateTimeField(models.DateTimeField):
def pre_save(self, model_instance, add):
return timezone.now()
#usage
created_at = models.DateField(default=timezone.now)
updated_at = AutoDateTimeField(default=timezone.now)
你可以使用timezone.now()来创建,auto_now来修改:
from django.utils import timezone
class User(models.Model):
created = models.DateTimeField(default=timezone.now())
modified = models.DateTimeField(auto_now=True)
如果使用自定义主键而不是默认的自增整型,auto_now_add将导致错误。
下面是Django默认DateTimeField的代码。Pre_save withauto_now和auto_now_add:
def pre_save(self, model_instance, add):
if self.auto_now or (self.auto_now_add and add):
value = timezone.now()
setattr(model_instance, self.attname, value)
return value
else:
return super(DateTimeField, self).pre_save(model_instance, add)
我不确定add参数是什么。我希望它会像这样:
add = True if getattr(model_instance, 'id') else False
新记录将没有attr id,因此getattr(model_instance, 'id')将返回False,将导致在字段中不设置任何值。