Django auto_now 和 auto_now_add [英] Django auto_now and auto_now_add

查看:29
本文介绍了Django auto_now 和 auto_now_add的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于 Django 1.1.

我的models.py中有这个:

class User(models.Model):created = models.DateTimeField(auto_now_add=True)修改 = 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: 警告:列'已创建' 不能为空[Sun Nov 15 02:18:12 2009] [error] 返回 self.cursor.execute(query, args)

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

 `created` datetime NOT NULL,`修改的`日期时间不为空,

这是否值得关注?

附带问题:在我的管理工具中,这两个字段没有显示.这是预期的吗?

解决方案

任何带有 auto_now 属性集也将继承 editable=False,因此不会显示在管理面板中.过去一直在谈论制作 auto_nowauto_now_add 参数消失了,虽然它们仍然存在,但我觉得你最好只使用 自定义save()方法.>

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

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

from django.utils 导入时区类用户(模型.模型):created = models.DateTimeField(editable=False)修改 = 模型.DateTimeField()def save(self, *args, **kwargs):''' 保存时,更新时间戳 '''如果不是 self.id:self.created = timezone.now()self.modified = timezone.now()return super(User, self).save(*args, **kwargs)

希望这有帮助!

根据评论进行

我坚持重载 save() 与依赖这些字段参数的原因有两个:

  1. 上述的起起落落及其可靠性.这些论点严重依赖于 Django 知道如何与之交互的每种类型的数据库处理日期/时间戳字段的方式,并且似乎在每个版本之间中断和/或更改.(我相信这就是要求完全删除它们的推动力).
  2. 事实上,它们仅适用于 DateField、DateTimeField 和 TimeField,通过使用此技术,您可以在每次保存项目时自动填充任何字段类型.
  3. 使用django.utils.timezone.now() vs. datetime.datetime.now(),因为它会返回一个TZ-aware或naive datetime.datetime 对象取决于 settings.USE_TZ.

为了解决 OP 看到错误的原因,我不确切知道,但看起来 created 甚至根本没有被填充,尽管有 auto_now_add=True.对我来说,它是一个错误,并强调了我上面的小列表中的第 1 项:auto_nowauto_now_add 充其量是片状的.

For Django 1.1.

I have this in my models.py:

class User(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)

When updating a row I get:

[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)

The relevant part of my database is:

  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,

Is this cause for concern?

Side question: in my admin tool, those two fields aren't showing up. Is that expected?

解决方案

Any field with the auto_now attribute set will also inherit editable=False and therefore will not show up in the admin panel. There has been talk in the past about making the auto_now and auto_now_add arguments go away, and although they still exist, I feel you're better off just using a custom save() method.

So, to make this work properly, I would recommend not using auto_now or auto_now_add and instead define your own save() method to make sure that created is only updated if id is not set (such as when the item is first created), and have it update modified every time the item is saved.

I have done the exact same thing with other projects I have written using Django, and so your save() would look like this:

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)

Hope this helps!

Edit in response to comments:

The reason why I just stick with overloading save() vs. relying on these field arguments is two-fold:

  1. The aforementioned ups and downs with their reliability. These arguments are heavily reliant on the way each type of database that Django knows how to interact with treats a date/time stamp field, and seems to break and/or change between every release. (Which I believe is the impetus behind the call to have them removed altogether).
  2. The fact that they only work on DateField, DateTimeField, and TimeField, and by using this technique you are able to automatically populate any field type every time an item is saved.
  3. Use django.utils.timezone.now() vs. datetime.datetime.now(), because it will return a TZ-aware or naive datetime.datetime object depending on settings.USE_TZ.

To address why the OP saw the error, I don't know exactly, but it looks like created isn't even being populated at all, despite having auto_now_add=True. To me it stands out as a bug, and underscores item #1 in my little list above: auto_now and auto_now_add are flaky at best.

这篇关于Django auto_now 和 auto_now_add的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆