修改 Django 管理页面上的操作顺序以填充历史表

Modify order of operations on Django admin pages to populate history tables

我创建了一种非常简单的方法来存储 Django 模型的历史记录:

class Estimate(Model):
    date = models.DateField(default=timezone.now)
    amount = models.DecimalField(max_digits=11, decimal_places=2, default=0.00)

    def makeHistory(self):
        history = new EstimateHistory()
        history.date = self.date
        history.amount = self.amount
        history.last_mod_date = timezone.now()
        history.last_mod_user = 'username'

class EstimateHistory(Model):
    # Same fields as Estimate...
    date = models.DateField(default=timezone.now)
    amount = models.DecimalField(max_digits=11, decimal_places=2, default=0.00)

    # ...with two more added as History metadata
    last_mod_date = models.DateTimeField("last modified date")
    last_mod_user = 'username'     

我已经重写了 Modelsave() 方法,为此:

def save(self, *args, **kwargs):
    try:
        # Is there a history table? Save off the object in it.
        historyObject = self.makeHistory()                             # <-- Line A
        print "Saving " + str(type(self)) + ", in a history table"
        super(Model, self).save(*args, **kwargs)
        historyObject.save()
    except AttributeError:
        print "Saving " + str(type(self)) + ", but not in a history table"
        super(Model, self).save(*args, **kwargs)
    except Error:
        print "Not even saving. Something went wrong."
        raise

这似乎工作正常,除了存储历史的全部要点是在保存对象之前存储值。

我正在使用管理页面对此进行测试,但如果我更改

Date:      2015-01-01
Estimate:  1500.00

Date:      2015-01-01
Estimate:  1700.00

上面A行调用makeHistory()时,self.amount的值为1700.00。也就是说,管理页面正在更改当前加载的模型,然后再将其保存在数据库中。

如何在管理页面中进行更改之前获取模型的原始内容,以便将它们保存在历史记录中table?使用上面的示例,我希望 EstimateHistory 中的 amount 字段为 1500.00,而不是 1700.00。

我是 Django 的新手(甚至 Python),所以请保持温柔。

我认为常见的方法是使用模型 __init__() 来记住那里的价值。像这样(未经测试的粗略示例):

class Estimate(Model):
    def __init__(self, *args, **kwargs):
        super(Estimate, self).__init__(*args, **kwargs)
        # use a different name to record what the old value is
        self.initial_amount = self.amount

    def make_history(self):
        old_value = self.initial_amount
        new_value = self.amount
        # etc etc

我不是特别喜欢上面这种记录历史的方式,因为很麻烦,每次记录历史都要这样写。对于我自己的项目,我使用 django-simple-history,它很容易用于跟踪历史记录。你不需要做我上面提到的任何事情,你可以跟踪你想要的任何模型历史。