2010-11-11 29 views
4

我有兩個型號可以說:存儲一個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) 

「my_model」用數據填充(FIELDA和fieldB下)。每當有人編輯「my_model的領域和撲救,我不想保存在這個模型的變化,但希望將其保存爲新行中的所有值‘my_model_history’,除了一個‘理由’領域,而‘my_model’數據保持不變。

什麼是自定義模板,自定義視圖,模型管理員等等等等方面接近這種情況下最好的辦法我是不是做正確嗎?

給我的問題上面某種意義上說,在我的項目,數據的下「my_model」的本質是市場價格,我需要保持所有的市場價格曾經與編輯一個「理由」主編的歷史。

+3

我不知道它是否適合你的需要,但Django的逆轉(https://github.com/etianen/django-reversion)是用於管理模型的歷史上一個非常方便的解決方案! – 2010-11-11 18:01:34

+0

嗯,這是一個良好的擴展性,但是,更多的是有幫助的事物的發展方面,並提供了很多什麼都沒有與我要求的其他功能性。實施這可能是我所需要的矯枉過正。 – sysasa 2010-11-12 13:48:35

+0

你有沒有看中的解決方案? – 2011-02-11 21:46:59

回答

1

我的解決方案:

肯定。我下面一個簡單快捷的解決方案如下: 創建三種模式與此類似:

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()信號:

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. 領域的-populated從 my_model數據行的值
  2. 場B -populated其值從 my_model數據行
  3. 原因-empty文本框
  4. history_entry_for從視圖-hidden

用戶現在可以編輯fieldA/fieldB。輸入一個理由。按保存觸發上面的信號。 保存前,

  1. 信號將交換價值 之間的主要模式(舊值)和 歷史模型(新價值)
  2. 更換,並保存主力機型行 (新值)。
  3. 插入並保存新的行中的 歷史模型(用舊值) 一個原因。

希望它有幫助。讓我知道是否還有其他問題。

2

相反編輯現有條目,爲什麼不使用該條目作爲初始數據的形式來創建一個新的實例?新的對象得到保存,原來保持不變...

+0

嗯。我會嘗試這種方法。將不斷更新解決方案或防止出現任何問題。謝謝!下面 – sysasa 2010-11-12 13:45:15

+0

解決方案: – sysasa 2011-03-01 17:38:22

0

我發現了一個解釋,以保留詳細的編輯歷史在書'親Django'頁面264。通讀後我會嘗試執行什麼我需要。將在這裏發佈我的方法時,我做了

+1

5年,還沒有讀完? – yoshi 2015-04-27 12:06:25

相關問題