django - 值更改后自动更新日期

ils*_*tam 13 python django datetime python-3.x

在以下django模型中:

class MyModel(models.Model):
    published = models.BooleanField(default=False)
    pub_date = models.DateTimeField('date published')
Run Code Online (Sandbox Code Playgroud)

我希望每次发布的字段更改为True时,都会使用当前日期自动更新pub_date字段.

什么是聪明的方式?

谢谢.

Ala*_*air 9

如果您将对象设置为在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)
Run Code Online (Sandbox Code Playgroud)

如果要在其他位置设置已发布的标志,则可以覆盖该save()方法或使用该pre_save信号.这不是那么优雅,因为很难判断published旗帜是否已经改变.我想你需要从数据库中重新获取对象来检查.


Eri*_*och 8

您想要添加auto_now字段并将其设置为True.每次更新模型时,这将使用当前时间戳进行更新.

pub_date = models.DateTimeField('date_published', auto_now=True)
Run Code Online (Sandbox Code Playgroud)

你可以在这里阅读它


编辑

对不起,您真的只想更改publish的值设置为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)
Run Code Online (Sandbox Code Playgroud)

  • 我不想每次更新模型时都更新时间戳。我只想更新它,只有当发布的字段更改为 True 时。 (2认同)

Bog*_*oie 8

如果发布已从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)
Run Code Online (Sandbox Code Playgroud)


ils*_*tam 7

所有的答案都很有用,但我终于这样做了:

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)
Run Code Online (Sandbox Code Playgroud)