首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django auto_now和auto_now_add

Django auto_now和auto_now_add
EN

Stack Overflow用户
提问于 2009-11-15 16:47:57
回答 13查看 310.2K关注 0票数 320

用于Django 1.1。

我的models.py中有以下内容:

代码语言:javascript
运行
复制
class User(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

当更新一行时,我得到:

代码语言:javascript
运行
复制
[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)

我的数据库的相关部分是:

代码语言:javascript
运行
复制
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,

这是值得关注的原因吗?

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

EN

回答 13

Stack Overflow用户

回答已采纳

发布于 2009-11-15 17:26:31

任何设置了auto_now属性的字段也将继承editable=False,因此不会显示在管理面板中。过去一直有关于消除auto_nowauto_now_add参数的讨论,尽管它们仍然存在,但我觉得只使用custom save() method会更好。

因此,为了使其正常工作,我建议不要使用auto_nowauto_now_add,而是定义您自己的save()方法,以确保created仅在未设置id时才更新(例如,当项目首次创建时),并让它在每次保存项目时更新modified

我对我用Django编写的其他项目做了完全相同的事情,所以你的save()应该是这样的:

代码语言:javascript
运行
复制
from django.utils import timezone

class User(models.Model):
    created     = models.DateTimeField(editable=False)
    modified    = models.DateTimeField()

    def save(self, *args, **kwargs):
        ''' On save, update timestamps '''
        if not self.id:
            self.created = timezone.now()
        self.modified = timezone.now()
        return super(User, self).save(*args, **kwargs)

希望这能有所帮助!

回复评论的编辑:

我坚持使用重载save()而不是依赖这些字段参数的原因有两个:

  1. 上述的起伏和它们的可靠性。这些参数在很大程度上依赖于Django知道如何与之交互的每种类型的数据库处理日期/时间戳字段的方式,并且似乎在每个版本之间中断和/或更改。(我相信这是让它们删除的原因,因为它们只适用于DateField、DateTimeField和TimeField,并且通过使用这种技术,您可以在每次保存项时自动填充任何字段类型。
  2. 使用django.utils.timezone.now()datetime.datetime.now(),因为它将返回TZ感知或朴素的datetime.datetime对象

为了解释为什么OP会看到这个错误,我不知道确切的原因,但是尽管有auto_now_add=True,但是看起来created根本没有被填充。对我来说,它是一个突出的错误,并强调了我上面的小列表中的第一项:auto_nowauto_now_add充其量也是不稳定的。

票数 434
EN

Stack Overflow用户

发布于 2010-07-26 01:01:36

但我想指出,在accepted answer中表达的意见有点过时。根据最近的讨论(django bug #7634#12785),auto_nowauto_now_add将无处可去,即使您转到original discussion,您也会发现在自定义保存方法中反对RY (就像在DRY中一样)的强烈论点。

已经提供了一个更好的解决方案(自定义字段类型),但没有获得足够的势头来进入django。您可以在三行代码中编写自己的代码(它是Jacob Kaplan-Moss' suggestion)。

代码语言:javascript
运行
复制
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)
票数 209
EN

Stack Overflow用户

发布于 2012-07-25 17:25:42

谈到一个次要问题:如果您想在管理中看到这些字段(但是,您将无法对其进行编辑),可以将readonly_fields添加到您的管理类中。

代码语言:javascript
运行
复制
class SomeAdmin(ModelAdmin):
    readonly_fields = ("created","modified",)

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

票数 40
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1737017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档