django对象更新,跟踪和比较更改

时间:2015-10-19 22:10:56

标签: django updates

我有一个具有属性值的对象。价值可以每周更新,例如周一由用户提供。

我希望能够按周数显示对象值,例如wk35值,wk36值... wk40值。

我希望能够比较历史值并获得百分比变化。

我不知道的是:

我应该为我的对象创建属性,例如

dateCreated会 dateupdated(因此它包含特定日期的最后一次更新) dateedited(因此用户可以在一天内多次编辑值)

我理解用户可以在很短的时间内编辑值,但应该能够在当天更新一次最终编辑。

我正在努力实现上述观念的概念。我已经开始阅读简单历史记录,它可以帮助我实现跟踪更改,但我不知道如何实现上面所写的内容。

我的模特课是:

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)    

2 个答案:

答案 0 :(得分:1)

可能有一些第三方模块为您执行此操作,但我最好的家庭酿造建议是一个记录表。如果您需要按日期将日志条目设置为唯一,则只需修改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)

答案 1 :(得分:0)

这是一个非常广泛/高级别的问题,但基本上您应该将历史数据/更改与模型分开存储。

以这种方式思考:您的模型是一个活生生的实体,它具有当前状态。您可以定期获取该状态的快照(数据)。稍后,您可以使用这些快照将模型的历史记录拼凑在一起(例如,可视化它如何随时间变化)。这基本上是 Memento pattern

所以,考虑一下你的需求。您的模型快照应该具有什么“分辨率”?也就是说,它应该存储每个数据点还是只存储几个?它应该存储每个用户的每一个更改,还是每周只拍一次快照?如果它只是每周一次,正如你的建议,只需运行一个cron作业,将模型数据复制到另一个模型......或另一个数据库,或者你甚至可以将它写成一个扁平的JSON或CSV文件!

或者......如果您希望能够像某个时间点那样完全重建模型,请考虑像 django-reversion 这样的包。

另一方面,如果只跟踪一个或两个真正重要的数字,你可以创建一个模型,将原始模型的id存储为外键,重要数字值和a时间戳。

编辑:如果你想要保留的只是一个ZoneSubStage.value,那么Dotcomly的答案提供了一个很好的实现。为了更好地将日志与模型分离,我建议使用 post_save signal 来创建日志条目,而不是覆盖模型的保存方法。