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 - 值更改后自动更新日期的主要内容,如果未能解决你的问题,请参考以下文章

当另一个单元格的值发生变化时,一个单元格中的自动日期更新(通过公式计算)

重新安排时自动更新Outlook会议提醒

怎么改ppt时间改为自动更新

当用户更改下拉过滤器中的值时,Django过滤更新查询

django django 有像 cakephp 这样的自动时间戳创建/更新字段吗?

R中的自动更新日期(总是在昨天查询)