对于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,

这值得关注吗?

小问题:在我的管理工具中,这两个字段没有显示。这是意料之中的吗?


当前回答

至于你的管理显示,请看这个答案。

注意:auto_now和auto_now_add默认设置为editable=False,这就是为什么适用这个。

其他回答

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)

我今天工作也需要类似的东西。默认值是时区.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选项

说一个题外话:如果你想在管理中看到这些字段(虽然,你不能编辑它),你可以把readonly_fields添加到你的管理类中。

class SomeAdmin(ModelAdmin):
    readonly_fields = ("created","modified",)

好吧,这只适用于最新的Django版本(我相信是1.3及以上版本)

class Feedback(models.Model):
    feedback = models.CharField(max_length=100)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)

在这里,我们创建了列,并在列创建时和有人修改反馈时使用时间戳进行更新。

Auto_now_add将设置实例创建的时间,而auto_now将设置某人修改反馈的时间。