我有一个具有属性值的对象。值可以按周更新,例如按用户星期一更新。
我希望能够按周数显示对象值,例如wk35值,wk36值…wk40价值。
我希望能够比较历史值并获得百分比变化。
我不知道的是:
我应该为我的对象创建属性吗?例如
datecreatedDateupdated(因此它包含特定日期的最后更新)日期编辑(因此用户可以在一天内多次编辑值)
我理解用户可以编辑几次值,但应该能够在当天更新一次最终编辑。
我正在与上述想法的概念作斗争。我已经开始阅读simple-history,它可以帮助我实现跟踪变化,但我不知道如何实现上面写的。
我的模型类是:
class ZoneSubStage(models.Model):
zone = models.ForeignKey(Zone)
substage = models.ForeignKey(SubStage)
value = models.PositiveSmallIntegerField(default=0)
slug = models.SlugField(unique=True)
history = HistoricalRecords()
created = models.DateTimeField(auto_now_add=True)
date = models.DateField(null=True)
可能有一些第三方模块为您做这件事,但我最好的家庭自制建议是一个日志表。如果您需要日志条目按日期唯一,则只需修改ZoneSubStage.save()
方法以按当前日期查找ZoneSubStageLog
,然后再简单地创建一个新的(我认为您需要,但将留给您)。
from django.db import transaction
class ZoneSubStage(models.Model):
zone = models.ForeignKey(Zone)
substage = models.ForeignKey(SubStage)
value = models.PositiveSmallIntegerField(default=0)
slug = models.SlugField(unique=True)
history = HistoricalRecords()
created = models.DateTimeField(auto_now_add=True)
date = models.DateField(null=True)
def __init__(self, *args, **kwargs):
super(ZoneSubStage, self).__init__(*args, **kwargs)
self.value_original = self.value
def save(self, **kwargs):
with transaction.atomic():
response = super(ZoneSubStage, self).save(**kwargs)
if self.value_original != self.value:
zone_log = ZoneSubStageLog()
zone_log.zone_sub_stage = self
zone_log.value = self.original_value
zone_log.save()
return response
class ZoneSubStageLog(models.Model):
zone_sub_stage = models.ForeignKey(ZoneSubStage)
value = models.PositiveSmallIntegerField(default=0)
date = models.DateField(auto_now_add=True)
这是一个非常广泛/高级别的问题,但基本上您应该将历史数据/更改与模型分开存储。
这样想:你的模型是一个活生生的实体,它有一个当前状态。您可以定期对该状态(数据)进行快照。稍后,您可以使用这些快照来拼凑模型的历史(例如,可视化它是如何随时间变化的)。这基本上就是Memento模式。
所以,考虑你的需求。你的模型快照应该有什么样的"分辨率"?也就是说,它应该存储每个数据点还是只存储几个数据点?它应该存储每个用户的每个更改,还是每周只拍一次快照?如果只是一周一次,正如您建议的那样,只需运行一个cron作业,将模型数据复制到另一个模型…或者另一个数据库,或者你甚至可以把它写成一个简单的JSON或CSV文件!
还是……如果你想重建模型,就像它在某个时间点一样,考虑一个像django- version的包。
另一方面,如果只有一个或两个真正重要的数字需要跟踪,您可以创建一个模型,该模型将原始模型的id存储为外键、重要的数字值和时间戳。
编辑:Dotcomly的答案提供了一个很好的实现,如果所有你想保持的是一个ZoneSubStage.value。为了更好地将日志与模型分离,我建议使用 post_save
信号来创建日志条目,而不是覆盖模型的保存方法。