将django模型的编辑历史记录存储在另一个自定义模型中

时间:2010-11-11 17:45:32

标签: django history models

我有两个模型可以说:

class superfields(Model):
    fieldA = models.FloatField()
    fieldB = models.FloatField()
    class Meta:
        abstract = True

class my_model( superfields ):
    def has_history( self ):
        return self.my_model_history_set.count() > 0

class my_model_history( superfields ):
    reason = models.TextField()
    mymodel = models.ForeignKey( my_model )

'my_model'填充了数据(在fieldA和fieldB下)。每当有人编辑'my_model的字段并保存时,我不想在此模型中保存更改,但希望将其存储为包含'my_model_history'中所有值的新行,以及'my_model'时的'reason'字段数据保持不变。

在自定义模板,自定义视图,模型管理员等方面处理此方案的最佳方法是什么?我是否正确执行此操作?

为了提出我的问题,在我的项目中,'my_model'下的数据性质是市场价格,我需要保留所有编辑过的市场价格的历史记录,并带有编辑的“理由”。 / p>

3 个答案:

答案 0 :(得分:2)

为什么不使用该条目作为表单的初始数据来创建新实例,而不是编辑现有条目?新对象被保存,原始文件保持不变......

答案 1 :(得分:2)

我的解决方案:

是肯定的。我所遵循的简单快速的解决方案如下: 我创建了三个类似的模型:

class my_super_abstract_model(Model):
    #All fields I need to keep a history for:
    fieldA = models.FloatField()
    fieldB = models.FloatField()
    class Meta:
        abstract = True

class my_model( my_super_abstract_model ):
    def has_history( self ):
        return self.my_model_history_set.count() > 0

class my_model_history( my_super_abstract_model ):
    reason = models.TextField()
    history_entry_for = models.ForeignKey( my_model )

我已经设置了一个信号:

pre_save.connect( create_history, 
                  sender = my_model_history )
保存在my_model_history中之前,pre_save()信号调用

和'create history':

def create_history(sender, **kwargs):
    #get variables passed by the pre-save signal:
    history_model = kwargs['instance']
    # Get main model object
    main_model = history_model.history_entry_for
    # swap all common fields between history edit and main model (except id)  
    main_model_fields = [f.name for f in main_model._meta.fields]
    history_model_fields = [f.name for f in history_model._meta.fields]
    field_index = list( [f for f in history_model_fields if f in main_model_fields and f != 'id' and f != 'created_date' ] )
    #loop thru to swap values:
    for field_name in field_index:
        temp = getattr(main_model, field_name)
        setattr( main_model, field_name, getattr( history_model, field_name ) )
        setattr( history_model, field_name, temp)
    # After the swap, save main model object here 
    main_model.save()

每当用户点击my_model行进行编辑时,我会使用“my_model_history”生成我的编辑表单,并使用用户选定行的值填充它。 (写了一个视图和模板来做到这一点)

因此编辑表单现在将具有:

  1. 字段A - 使用来自的值填充 my_model数据行
  2. 字段B - 用来自的值填充 my_model数据行
  3. Reason -empty文本框
  4. history_entry_for -hidden from view
  5. 用户现在可以编辑fieldA / fieldB。输入原因。按保存以触发上面的信号。 保存之前,

    1. 信号将交换两者之间的值 主要模型(旧值)和 历史模型(新值)
    2. 替换并保存主模型行 (使用新值)。
    3. 在中插入并保存新行 历史模型(具有旧值) 有理由。
    4. 希望它有所帮助。如果还有其他问题,请告诉我。

答案 2 :(得分:0)

我找到了关于在书中保留详细编辑历史的解释' pro Django'在阅读完之后,我将尝试实现我需要的东西。我完成后会发布我的方法