将django模型的编辑历史存储在另一个自定义模型中 [英] Storing the edit history of a django model in another custom model

查看:110
本文介绍了将django模型的编辑历史存储在另一个自定义模型中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个模型可以说:

  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)
/ pre>

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



根据自定义模板,自定义视图,模型管理员等来处理这种情况的最佳方法是什么?我正在做正确的?



为了让我的问题更有意义,在我的项目中,my_model下的数据的性质是市场价格,我需要保持所有市场价格历史,

解决方案

我的解决方案:



是的。我所追踪的一个简单而快速的解决方案如下:
我创建了类似于以下的三个模型:

  class my_super_abstract_model (模型):
#所有字段我需要保留以下历史:
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>

我设置了一个信号:

  pre_save。连接(create_history,
sender = my_model_history)

和创建历史记录保存在my_model_history中的pre_save()信号:

  def create_history(sender,** kwargs):
#get通过预先保存信号传递的变量:
history_model = kwargs ['instance']
#获取主模型对象
main_model = history_model.history_entry_for
#交换历史记录之间的所有常用字段编辑和主模型(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 history in history_mo del_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)
#交换后,在这里保存主模型对象
main_model.save()

每当用户单击my_model行进行编辑时,我使用'my_model_history'生成我的编辑表单,并使用用户选择的行中的值填充它。 (已经写了一个视图和模板)



所以编辑表单现在将有:


  1. 字段A包含来自
    my_model数据行的值
  2. 字段使用
    my_model数据行
  3. 中的值填充b $ b
  4. 原因 - 空文本框

  5. history_entry_for -hidden from view

用户现在可以编辑fieldA / fieldB。输入原因按保存触发上述信号。
在保存之前,


  1. 信号将交换主模型(旧值)和$ b $之间的
    之间的值b历史模型(新值)

  2. 替换并保存主模型行
    (使用新值)。

  3. 插入并保存
    历史模型中的新行(具有旧值)
    有原因。

希望它帮助。如果还有其他问题,请通知我。


I have two models lets say:

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' is populated with data (under fieldA and fieldB). Whenever someone edits 'my_model's fields and saves, I don't want to save the change in this model but want to store it as a new row with all values in 'my_model_history', in addition to a 'reason' field while 'my_model' data stays the same.

What is the best way to approach this scenario in terms of custom templates, custom views, model admins etc etc. Am I doing it correctly?

To give my question above some sense, in my project, the nature of data under 'my_model' is market prices and I need to maintain a history of all the market prices ever edited with a 'reason' for the edit.

解决方案

My Solution:

yes. A simple and quick solution I am following is as follows: I create three models similar to this:

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 )

I've setup a signal:

pre_save.connect( create_history, 
                  sender = my_model_history )

and 'create history' to be called by the pre_save() signal before saving in my_model_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()

Whenever user clicks on a my_model row for editing, I use 'my_model_history' to generate my edit form and populate it with the values from the user selected row. (Have written a view and template to do that)

So the edit form will now have:

  1. field A -populated with values from my_model data row
  2. field B -populated with values from my_model data row
  3. Reason -empty text box
  4. history_entry_for -hidden from view

User can now edit fieldA/fieldB. Enter a reason. Press save to trigger the signal above. Before saving,

  1. Signal will swap the values between the main model(old values) and history model(New values)
  2. Replace and save the main model row (with the new values).
  3. Insert and save a new row in the history model (with the old values) with a reason.

Hope it helps. Let me know if there are any further questions.

这篇关于将django模型的编辑历史存储在另一个自定义模型中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆