2013-04-18 25 views
2

我有我的models.py如何檢查模型中的特定字段更改?

class Hotel(models.Model): 
    name = models.CharField(max_length=20) 
    currency = models.ForeignKey(Currency) 


class Currency(models.Mode): 
    code = models.CharField(max_length=3) 
    name = models.CharField(max_length=10) 

每當在酒店的currency領域正在發生變化,我需要能夠做一些事情。所以我有這樣一個功能:

@receiver(pre_save,sender=Hotel) 
def update_something(sender,**kwargs) 
    obj = kwargs['instance'] 
    old_object = Hotel.objects.get(pk=obj.pk) 
    ''' 
    Now I can do anything here comparing the oldo object with the instance 
    ''' 

的事情是我不想讓這個查詢,從此信號的目的變得愚蠢和我成爲傻子。

所以我應該可以做這樣的事情:

updated = kwargs['update_fields'] 
new_currency = updated['currency'] 

是他們的辦法,我可以找出是隻改變一個特定領域說currency,而不是做這樣的查詢。我想在保存之前獲取與currency外鍵相關的更改並更新內容。

對不起,我的英語不好,不能使用太專業術語。

謝謝:)

+0

我想你會發現你需要的一切:http://stackoverflow.com/questions/1197674/actions-triggered-by-field-change-in-django。你可以使用__init__和__save__方法重寫它們,或者重寫__setter__! – Ricola3D

+0

[Django:保存時,如何檢查字段是否已更改?]的可能重複(http://stackoverflow.com/questions/1355150/django-when-saving-how-can-you-check-if-一個場-具有改變的) – Martey

回答

1

而哈克的解決辦法是,以節省初始化對象的狀態。

from django.forms.models import model_to_dict 

class Currency(models.Mode): 
    code = models.CharField(max_length=3) 
    name = models.CharField(max_length=10) 

    def __init__(self): 
     super(Currency, self).__init__() 
     self.__state = model_to_dict(self) 

    def updated(self): 
     new_state = model_to_dict(self) 
     return dict(set(self.__state.iteritems()) - set(new_state.iteritems())) 

方法updated將返回初始和新狀態之間的差異。

2

的信號點是更好的去耦 - 允許其他應用程序(你不一定知道還)透明地掛接到您的應用程序和/或避免應用程序之間的循環依賴。在這裏使用信號確實沒有意義(除非信號處理程序在另一個應用程序中,並且您不希望具有HotelCurrency模型的應用程序依賴於此其他應用程序)。

要回答你的問題:做一個查詢來檢索原始狀態是唯一可以比較存儲值和當前值的方法。現在,如果你只是在一個特定領域的興趣的話,你當然不必檢索整個模型的實例 - 只需使用queryset.values_list

old_currency = Hotel.objects.filter(pk=obj.pk).values_list("currency", flat=True)[0] 
相關問題