2012-10-18 3 views
12

시간을내어 감사합니다.Django - 저장 메소드를 재정의 할 때 이전 값과 새 값 사이의 차이점을 확인하십시오

나는 장고 1.4를 사용하고 있으며, 다음과 같은 코드를 가지고있다 : Quest 모델의 오버 라이딩 된 저장 메소드.

@commit_on_success 
def save(self, *args, **kwargs): 
    from ib.quest.models.quest_status_update import QuestStatusUpdate 
    created = not self.pk 

    if not created: 
     quest = Quest.objects.get(pk=self) 
     # CHECK FOR SOME OLD VALUE 
    super(Quest, self).save(*args, **kwargs) 

나는 이것을하는 현명한 방법을 찾을 수 없었다. 이전 인스턴스 값을 찾기 위해 현재 업데이트하고있는 객체에 대한 새 쿼리를 만들어야한다는 것은 매우 어리석은 일입니다.

더 좋은 방법이 있나요?

감사합니다. 당신이 자신을 그렇게 나 다른 쿼리 이전에 저장 수행해야하므로

시스코

+0

업데이트 컨텍스트 란 무엇입니까? 즉. 모델 또는 ModelForm 등을 통해 직접 볼 수 있습니까? – jondykeman

+0

글쎄,이게 정말 관련이 있니? 인스턴스를 업데이트하는 메서드를 저장 중입니다. 하지만 어쨌든이 호출은 뷰에서 만들어지며 거기에서'quest.save() '를 호출했습니다. – Francisco

+0

나는이를 수행 할 수있는 확실한 방법이 있는지 확신하지 못합니다. 오래된 객체를'save()'메쏘드에 전달하거나'save()'에 쿼리 할 수 ​​있습니다. – Rohan

답변

9

장고 모델 인스턴스의 이전 값을 캐시하지 않습니다.

하나 개의 일반적인 패턴은 사용하는 것입니다 미리 저장 신호를 (또는 당신이했던대로, 당신의 저장() 메소드에서 직접이 코드를 넣어) :

old_instance = MyModel.objects.get(pk=instance.pk) 
# compare instance with old_instance, and maybe decide whether to continue 

을 당신의 캐시를 유지하려면 이전 값은, 그때는 아마보기 코드에서 그렇게 할 것 :

from copy import deepcopy 
object = MyModel.objects.get(pk=some_value) 
cache = deepcopy(object) 

# Do something with object, and then compare with cache before saving 

는 다른 가능한 솔루션뿐만 아니라, 이것에 대해 장고 - 개발자에 a recent discussion 있었다.

+0

솔루션에 감사드립니다. 이것은 작동하지만'save_as'를 사용할 경우 pk가'None'으로 설정됩니다. 이에 대한 해결 방법은 무엇입니까? –

1

장고 - 복귀 신호를 사용하여 이전 값과의 차이점을 확인하고 있지만 저장 신호에 동일한 논리가 적용됩니다. 내가 필드의 저장 여부를 저장하려는 차이점이 있습니다. 저장 및 삭제 방법에서 나중에 사용하기 위해 전체 개체를 복사 할 모두

def __init__(self, *args, **kwargs): 
    super(MyModel, self).__init__(*args, **kwargs) 
    self.old_my_field = self.my_field 

def save(self, *args, **kwargs): 
    print self.old_my_field 
    print self.my_field 

당신은 아마 deepcopy 사용하거나 뭔가 :

@receiver(reversion.pre_revision_commit) 
def it_worked(sender, **kwargs): 
    currentVersion = kwargs.pop('versions')[0].field_dict 
    fieldList = currentVersion.keys() 
    fieldList.remove('id') 
    commentDict = {} 
    print fieldList 
    try: 
     pastVersion = reversion.get_for_object(kwargs.pop('instances')[0])[0].field_dict 
    except IndexError: 
     for field in fieldList: 
      commentDict[field] = "Created" 
     comment = commentDict 
    except TypeError: 
     for field in fieldList: 
      commentDict[field] = "Deleted" 
     comment = commentDict 
    else: 
     for field in fieldList: 
      try: 
       pastTest = pastVersion[field] 
      except KeyError: 
       commentDict[field] = "Created" 
      else:  
       if currentVersion[field] != pastTest: 
        commentDict[field] = "Changed" 
       else: 
        commentDict[field] = "Unchanged" 
     comment = commentDict 
    revision = kwargs.pop('revision') 
    revision.comment = comment 
    revision.save() 
    kwargs['revision'] = revision 
    sender.save_revision 
12

당신은 init 메소드 내부의 이전 값을 저장할 수 있습니다.

+0

매우 간단하고 읽기 쉽습니다. 게다가 완벽하게 작동합니다. 우수한 솔루션. –