Допустим, у меня есть следующие модели:
class Blog(TimeStampedModel):
summary = models.TextField()
text = models.TextField()
class BlogComment(TimeStampedModel):
author = models.CharField()
text = models.CharField()
blog = models.ForeignKey(Blog, models.CASCADE, related_name='comments')
class BlogTag(TimeStampedModel):
name = models.CharField()
blog = models.ForeignKey(Blog, models.CASCADE, related_name='tags')
Все три наследуются от следующей модели, которая реализует некоторую обработку меток времени:
class TimeStampedModel(models.Model):
last_changed = models.DateTimeField()
created_at = models.DateTimeField(default=timezone.now)
def save(self, *args, **kwargs):
try:
self._meta.get_field('blog')
except models.FieldDoesNotExist:
self.last_changed = timezone.now()
super(TimeStampedModel, self).save(*args, **kwargs)
else:
now = timezone.now()
self.blog.last_changed = now
self.last_changed = now
with transaction.atomic():
super(TimeStampedModel, self).save(*args, **kwargs)
self.blog.save()
class Meta:
abstract = True
Основная идея, лежащая в основе пользовательских save()
означает, что когда обновляется, например, комментарий (экземпляр BlogComment
), он должен обновить last_changed
отметку времени как экземпляра комментария, так и соответствующей записи в блоге.
К сожалению, настройка отметки временине идеален, поскольку он переопределяет временную метку блога, когда вызывается его собственное сохранение, а время просто немного отличается:
In [1]: b = Blog.objects.get(id=1)
In [2]: comment0 = t.comments.all()[0]
In [3]: b.last_changed, comment0.last_changed
Out[3]:
(datetime.datetime(2018, 6, 7, 12, 54, 12, 516855, tzinfo=<UTC>),
datetime.datetime(2018, 6, 7, 10, 22, 09, 201690, tzinfo=<UTC>))
In [4]: comment0.text
Out[4]: 'Some text'
In [5]: comment0.text = 'test'
In [6]: comment0.save()
In [7]: t = blog.objects.get(id=1)
In [8]: comment0 = t.comments.all()[0]
In [9]: t.last_changed, comment0.last_changed
Out[9]:
(datetime.datetime(2018, 6, 7, 13, 25, 58, 64131, tzinfo=<UTC>),
datetime.datetime(2018, 6, 7, 13, 25, 58, 61960, tzinfo=<UTC>))
Другая проблема заключается в том, что функция сохранения опирается на внешний ключ с именем blog
Это кажется странным, поскольку добавление моделей, использующих разные имена внешних ключей, требует обновления функции сохранения.
Существует ли более общее решение этой проблемы обновления временных меток связанных моделей?Как изменить указанную выше функцию save()
, чтобы последовательно обновлять модели с одинаковой отметкой времени?