Django - автоматически обновлять дату после изменения стоимости
В следующей модели django:
class MyModel(models.Model):
published = models.BooleanField(default=False)
pub_date = models.DateTimeField('date published')
Я хочу, чтобы поле pub_date автоматически обновлялось с текущей датой, каждый раз, когда опубликованное поле изменяется на True.
Каков умный способ?
Спасибо.
Ответы
Ответ 1
Все ответы были полезны, но я, наконец, сделал это так:
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)
Ответ 2
Если вы устанавливаете объект как опубликованный в администраторе 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
. Я думаю, что вам нужно повторно извлечь объект из базы данных, чтобы проверить.
Ответ 3
следующее только изменяет вашу pub_date, если опубликовано было изменено с False на True:
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)
Ответ 4
Вы хотите добавить поле auto_now и установить его в True. Это будет обновляться с текущей отметкой времени при каждом обновлении модели.
pub_date = models.DateTimeField('date_published', auto_now=True)
Вы можете прочитать об этом здесь
.Изменить
Извините, что вы действительно хотите изменить метку времени, когда значение опубликованного установлено в 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)
Ответ 5
Создайте метод publish()
:
def publish(self):
self.published = True
self.pub_date = datetime.datetime.now()
self.save()
Ответ 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