django - 值更改后自动更新日期
Posted
技术标签:
【中文标题】django - 值更改后自动更新日期【英文标题】:django - update date automatically after a value change 【发布时间】:2015-10-29 18:12:20 【问题描述】:在以下 django 模型中:
class MyModel(models.Model):
published = models.BooleanField(default=False)
pub_date = models.DateTimeField('date published')
我希望 pub_date 字段在每次发布字段更改为 True 时自动更新为当前日期。
什么是聪明的方法?
谢谢。
【问题讨论】:
【参考方案1】:您想添加 auto_now 字段并将其设置为 True。这将在您每次更新模型时使用当前时间戳进行更新。
pub_date = models.DateTimeField('date_published', auto_now=True)
你可以阅读它here
编辑
抱歉,您真的只是想在已发布的值设置为 True 时更改时间戳。一个非常简单的方法是获取模型的原始值,然后覆盖 save 方法,以便在设置为 True 时更新它。这是您添加到代码中的内容:
class MyModel(models.Model):
published = models.BooleanField(default=False)
pub_date = models.DateTimeField('date published')
def __init__(self, *args, **kwargs):
super(MyModel, self).__init__(*args, **kwargs)
self._published = self.published
def save(self, *args, **kwargs):
if not self._published and self.published:
self.pub_date = django.timezone.now()
super(MyModel, self).save(*args, **kwargs)
【讨论】:
我不想每次更新模型时都更新时间戳。我只想更新它,只有在发布的字段更改为 True 时。【参考方案2】:所有答案都很有用,但我终于这样做了:
def save(self, *args, **kwargs):
if self.published and self.pub_date is None:
self.pub_date = timezone.now()
elif not self.published and self.pub_date is not None:
self.pub_date = None
super(Model, self).save(*args, **kwargs)
【讨论】:
【参考方案3】:如果您将对象设置为在 Django 管理中发布,一个很好的方法是覆盖模型管理类的 save_model
方法。
from datetime import datetime
from django.contrib import admin
class MyModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
if obj.published and 'published' in form.changed_data
obj.pub_date = datetime.now()
obj.save()
admin.site.register(MyModel, MyModelAdmin)
如果您在别处设置已发布标志,则可以覆盖save()
方法,或使用pre_save
信号。这不那么优雅,因为很难判断 published
标志是否已更改。我认为您需要从数据库中重新获取对象以进行检查。
【讨论】:
非常有用!我还添加了这个条件:if obj.pub_date is None:
,因为我不想在用户发布、取消发布和发布帖子时覆盖旧的发布日期。
@Flimm 检查if obj.pub_date is None
可能是适合您的选择。但是,原始问题明确表示每次发布的字段更改为 True。
很公平。 (我会删除这条评论。)【参考方案4】:
如果发布已从 False 修改为 True,则以下内容只会更改您的 pub_date:
from datetime import datetime
def __init__(self, *args, **kwargs):
super(MyModel, self).__init__(*args, **kwargs)
self.old_published = self.published
def save(self, *args, **kwargs):
if self.published and self.old_published != self.published:
self.pub_date = datetime.now()
super(Model, self).save(*args, **kwargs)
【讨论】:
我喜欢这个,但是如果我发布、取消发布然后再次发布对象呢? @Ilias95 如果您取消发布,是否要将 pub_date 设置为空? 可能没关系。 在调用 super 之前的“self.old_published = self.published”将完成这项工作。根据需要编辑它。谢谢。【参考方案5】:创建publish()
方法:
def publish(self):
self.published = True
self.pub_date = datetime.datetime.now()
self.save()
【讨论】:
我希望能够只在 django 管理面板中选中相应的复选框,而无事可做。是否可以从那里调用此方法? @Ilias95 您需要将此答案与 Alasdair 在下面给出的答案结合起来。【参考方案6】:只是覆盖更新方法
from django.utils import timezone
class Vehicle(models.Model):
class Meta:
ordering = ['-created']
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(default=timezone.now)
def update(self, *args, **kwargs):
kwargs.update('updated': timezone.now)
super().update(*args, **kwargs)
return self
【讨论】:
以上是关于django - 值更改后自动更新日期的主要内容,如果未能解决你的问题,请参考以下文章
当另一个单元格的值发生变化时,一个单元格中的自动日期更新(通过公式计算)