对于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属性集的任何字段也将继承editable=False,因此不会显示在管理面板中。过去已经讨论过删除auto_now和auto_now_add参数,尽管它们仍然存在,但我认为最好使用自定义save()方法。
因此,为了使其正常工作,我建议不要使用auto_now或auto_now_add,而是定义自己的save()方法,以确保仅在未设置id时(例如当项目第一次创建时)才更新created,并在每次保存项目时更新修改它。
我用Django写的其他项目也做了同样的事情,所以你的save()看起来像这样:
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()而不是依赖这些字段参数的原因有两个:
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).
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.
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.
为了解决OP看到错误的原因,我不确切地知道,但它看起来像创建的甚至没有被填充,尽管有auto_now_add=True。对我来说,这是一个明显的错误,并强调了我上面小列表中的第一条:auto_now和auto_now_add充其量是不可靠的。
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)