次のDjangoモデル:
class MyModel(models.Model):
published = models.BooleanField(default=False)
pub_date = models.DateTimeField('date published')
公開されたフィールドがTrueに変わるたびに、pub_dateフィールドが現在の日付で自動的に更新されるようにしたい。
スマートな方法は何ですか?
ありがとう。
すべての答えは役に立ちましたが、私はついにこのようにしました:
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)
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
フラグが変更されたかどうかを判断するのが難しいため、これはエレガントではありません。確認するには、データベースからオブジェクトを再フェッチする必要があると思います。
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)
以下は、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)
publish()
メソッドを作成します。
def publish(self):
self.published = True
self.pub_date = datetime.datetime.now()
self.save()
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