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

这值得关注吗?

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


当前回答

你可以使用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,将导致在字段中不设置任何值。

其他回答

如果你像这样修改你的模型类:

class MyModel(models.Model):
    time = models.DateTimeField(auto_now_add=True)
    time.editable = True

然后这个字段将显示在我的管理更改页面

这值得关注吗?

不,在保存模型时,Django会自动为你添加它,所以,这是意料之中的。

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

由于这些字段是自动添加的,所以不会显示它们。

为了补充上面的内容,正如synack所说,django邮件列表中一直有关于删除它的争论,因为它“设计得不好”,是“一个黑客”。

在我的每个模型上编写自定义save()比使用auto_now要痛苦得多

显然,你不需要对每个模型都写。您可以将它写入一个模型,并从它继承其他模型。

但是,由于存在auto_add和auto_now_add,我宁愿使用它们,而不是自己尝试编写方法。

但我想指出,公认答案中所表达的观点有些过时。根据最近的讨论(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,将导致在字段中不设置任何值。

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将设置某人修改反馈的时间。