web-dev-qa-db-ja.com

django-値の変更後に日付を自動的に更新します

次のDjangoモデル:

class MyModel(models.Model):
    published = models.BooleanField(default=False)
    pub_date = models.DateTimeField('date published')

公開されたフィールドがTrueに変わるたびに、pub_dateフィールドが現在の日付で自動的に更新されるようにしたい。

スマートな方法は何ですか?

ありがとう。

14
ilstam

すべての答えは役に立ちましたが、私はついにこのようにしました:

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)
7
ilstam

Django adminで公開されているようにオブジェクトを設定している場合、これを行うための良い方法は、モデル管理クラスの _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フラグが変更されたかどうかを判断するのが難しいため、これはエレガントではありません。確認するには、データベースからオブジェクトを再フェッチする必要があると思います。

9
Alasdair

Auto_nowフィールドを追加して、Trueに設定します。これは、モデルを更新するたびに現在のタイムスタンプで更新されます。

pub_date = models.DateTimeField('date_published', auto_now=True)

あなたはそれについて読むことができます ここ


編集

申し訳ありませんが、publishedの値がTrueに設定されているときにタイムスタンプを変更したいだけです。これを行う非常に簡単な方法は、モデルの元の値を取得して、Trueに設定されたときに更新されるようにsaveメソッドをオーバーライドすることです。コードに追加するものは次のとおりです。

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)
8
Eric Bulloch

以下は、publishedが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)
8
Bogdan Goie

publish()メソッドを作成します。

def publish(self):
    self.published = True
    self.pub_date = datetime.datetime.now()
    self.save()
2
kylie.a

pdateメソッドのオーバーライドのみ

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
0
Jamil Noyda