Pau*_*jan 249 python django datetime django-models django-admin
对于Django 1.1.
我在models.py中有这个:
class User(models.Model):
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)
更新行时,我得到:
[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)
Run Code Online (Sandbox Code Playgroud)
我的数据库的相关部分是:
`created` datetime NOT NULL,
`modified` datetime NOT NULL,
Run Code Online (Sandbox Code Playgroud)
这引起关注吗?
附带问题:在我的管理工具中,这两个字段没有显示出来.这是预期的吗?
jat*_*ism 346
具有auto_now属性集的任何字段也将继承editable=False,因此不会显示在管理面板中.过去曾经有过关于让这些auto_now和auto_now_add论点消失的说法,虽然它们仍然存在,但我觉得你最好只使用自定义save()方法.
因此,为了使这项工作正常,我建议不要使用auto_now或auto_now_add改为定义自己的save()方法,以确保created只有在id未设置时才更新(例如首次创建项目时),并在modified每次项目时更新得救了.
我使用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)
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
编辑以回应评论:
我只是坚持重载save()与依赖这些字段参数的原因有两个:
django.utils.timezone.now()vs. datetime.datetime.now(),因为它将返回一个TZ感知或天真的datetime.datetime对象取决于settings.USE_TZ.为了解决OP看到错误的原因,我不确切地知道,但看起来created甚至根本没有填充,尽管有auto_now_add=True.对我而言,它突出了一个错误,并在我上面的小清单中强调了第一项: auto_now并且auto_now_add最多只是片状.
Sha*_*ger 159
Bah ...评论的声誉不够......但我想指出,在接受的答案中表达的观点有点过时了.根据最近的讨论(django错误#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 = models.AutoDateTimeField(default=timezone.now)
Run Code Online (Sandbox Code Playgroud)
Dat*_*eed 30
谈论一个附带问题:如果你想在admin中看到这个字段(但是你将无法编辑它),你可以添加readonly_fields到你的管理类.
class SomeAdmin(ModelAdmin):
readonly_fields = ("created","modified",)
Run Code Online (Sandbox Code Playgroud)
嗯,这仅适用于最新的Django版本(我相信,1.3及以上版本)
Jos*_*osh 26
我认为这里最简单(也可能是最优雅)的解决方案是利用您可以设置default为可调用的事实.因此,为了解决管理员对auto_now的特殊处理,你可以像这样声明字段:
from django.utils import timezone
date_filed = models.DateField(default=timezone.now)
Run Code Online (Sandbox Code Playgroud)
重要的是不要使用,timezone.now()因为默认值不会更新(即默认值仅在加载代码时才设置).如果你发现自己做了很多,你可以创建一个自定义字段.但是,我觉得这已经很干了.
Eri*_*eng 17
如果你改变你的模型类如下:
class MyModel(models.Model):
time = models.DateTimeField(auto_now_add=True)
time.editable = True
Run Code Online (Sandbox Code Playgroud)
然后,此字段将显示在我的管理员更改页面中
Edw*_*ell 12
根据我所读到的内容以及到目前为止我对Django的经验,auto_now_add是错误的.我同意jthanism ---覆盖正常的保存方法,它很干净,你知道什么是hapenning.现在,为了让它变干,创建一个名为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
Run Code Online (Sandbox Code Playgroud)
然后,当你想要一个具有这种时间戳行为的模型时,只需要子类:
MyNewTimeStampyModel(TimeStamped):
field1 = ...
Run Code Online (Sandbox Code Playgroud)
如果您希望字段显示在admin中,则只需删除该editable=False选项即可
这值得关注吗?
不,Django在保存模型时会自动为您添加它,因此是可以预期的。
附带问题:在我的管理工具中,这两个字段没有显示。那是预期的吗?
由于这些字段是自动添加的,因此不会显示。
就像synack所说的,除此之外,在django邮件列表上已经有辩论将其删除,因为它“设计得不好”并且是“黑客”。
与使用auto_now相比,在我的每个模型上编写自定义的save()要痛苦得多
显然,您不必将其写入每个模型。您可以将其写入一个模型并从中继承其他模型。
但是,因为auto_add和auto_now_add在那里,我会用他们,而不是试图写一个方法我自己。
class Feedback(models.Model):
feedback = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
Run Code Online (Sandbox Code Playgroud)
在这里,我们创建并更新了列,这些列在创建时和有人修改反馈时都会带有时间戳。
auto_now_add将设置创建实例的时间,而auto_now将设置某人修改其反馈的时间。
| 归档时间: |
|
| 查看次数: |
210115 次 |
| 最近记录: |