Django保留JSONField中一个字段的更改历史记录

时间:2016-11-22 22:58:48

标签: django django-models

我的模型看起来像这样:

htmlentities()

我尝试做的只是将新状态(如果已更改)附加到历史记录class Order(models.Model): ORDER_STATES = ( ('PAYMENT_IN_PROCCESS', _(u'payment_in_process')), ('PAYMENT_REJECTED', _(u'payment_rejected')), ('PAYMENT_ACCEPTED', _(u'payment_accepted')), ) state = models.CharField(max_length=150, blank=True, choices=ORDER_STATES, default='PAYMENT_IN_PROCCESS', db_index=True) history = JSONField(default=[], null=True, blank=True) .... def __init__(self, *args, **kwargs): super(Order, self).__init__(*args, **kwargs) self.__actual_state = self.state # important to keep self.history def save(self, *args, **kwargs): print("self.__actual_state: %s" % self.__actual_state) print("self.state: %s" % self.state) if self.state != self.__actual_state: # The state changed, change history actual_history = self.history print("actual_history: %s" % actual_history) new_history = actual_history.append({"state": self.state, "date": datetime.today()}) print("new_history: %s" % new_history) self.history = new_history super(Order, self).save(*args, **kwargs) 中保留的数据中。但是,JSONField打印new_history我不知道为什么。

2 个答案:

答案 0 :(得分:1)

append不返回任何内容,它会修改目标list。要做你想做的事,你必须这样做:

def save(self, *args, **kwargs):
    import copy
    print("self.__actual_state: %s" % self.__actual_state)
    print("self.state: %s" % self.state)
    if self.state != self.__actual_state:
        # The state changed, change history
        actual_history = self.history
        print("actual_history: %s" % actual_history)
        new_history = copy.copy(actual_history)
        new_history.append({"state": self.state, "date": datetime.today()})
        # of course, you can also just do
        # self.history.append(...) instead of copying and copying back
        print("new_history: %s" % new_history)
        self.history = new_history
    super(Order, self).save(*args, **kwargs)

答案 1 :(得分:1)

from_db vs __init __

在跟踪从数据库读入的数据时,过度使用from_db方法而不是__init__方法可以提供更好的控制。这是因为即使创建了一个新实例(而不是从数据库中读入),也会调用__init__方法。在这种情况下,没有任何历史记录可以保存。

  

from_db()方法可用于自定义模型实例创建   从数据库加载时。

使用JSONField

  

jsonb数据以分解的二进制格式存储   由于增加了转换开销,输入稍慢,但是   处理速度明显加快,因为不需要重新分析   来自:https://www.postgresql.org/docs/current/static/datatype-json.html

除非您经常阅读此存档数据,否则使用JSON只会增加不必要的开销。

更新和删除

如果您将历史记录保存为记录本身的一部分,则在删除记录时您将丢失它。

另请注意,如果您执行以下操作,则不会调用save方法:

Order.objects.filter(something=something).update(state='new state')

所以你将失去历史的一部分。

推荐解决实际问题的方法。

您正在使用postgresql,它对triggers和规则提供了很好的支持。它可以帮助您轻松维护历史记录,并更快,更准确地完成。

drew会说这是real problem (X)的解决方案。您提出的问题是您尝试解决问题(Y)到实际问题(X)的问题。

保存方法中问题的解决方案

正如在另一个答案中指出的那样,追加不会返回一个值,这就是历史为无的原因