2009-08-26 3 views
1

AuditTrail 코드를 수정하여 ForeignKey 필드를 복사하지 않고 오히려 관련 필드를 복사합니다 (즉, 내 데이터베이스 테이블에 외래 키를 원하지 않습니다. 감사 모델).Django : AuditTrail & Lazy Relations

내가 그렇게처럼 보이는 copy_field 기능을 작성했습니다 :

def copy_field(field): 
    while(isinstance(field, models.OneToOneField, models.ForeignKey)): 
     field = field.rel.get_related_field() 
    if isinstance(field, models.AutoField): 
     f = models.IntegerField() 
    else: 
     f = copy(field) 
    #...snip some adjusting of fs attributes... 
    return f 

AuditTrail 속성이 모델합니다 (class_prepared 신호를 통해) 준비 할 때이 코드가 실행됩니다. get_related_field() 호출이 실패합니다 field.rel.to는 관련 모델의 이름이 포함 된 문자열이보다는이기 때문에, - ForeignKey가 아직 준비되지 않은 모델에 필드에 관련 될 때

그러나,이 문제로 실행 모델 인스턴스.

나는이 문제를 해결하기 위해 무엇을 해야할지를 놓쳤다. 필드를 복사하기 전에 어떤 모델의 종속성을 확인하고 준비가 완료 될 때까지 기다려야합니까? 이 문제를 해결하는 가장 좋은 방법에 대한 아이디어가 있습니까?

답변

0

필자가 한 일은 모델이 가지고있는 모든 종속성을 나열하는 것이 었습니다 (정식 응용 프로그램/이름 쌍을 결정하고 이것을 결정하기 위해 django.db.models.fields.related에서 일부 코드 복사). 그리고 내 class_prepared 신호 처리기를 수정하여 내 타겟 모델.

처리기가 내 종속성 목록에서 모델을 인식하면 목록에서 해당 모델을 제거하고 목록이 비어 있는지 확인합니다. 그렇다면 감사 모델을 만드는 것이 좋습니다. 중요한 참고 사항은 모델을 만들기 전에 class_prepared 핸들러를 끊는 것입니다. 그렇지 않으면 무한 재귀가 발생합니다 (또는 더 구체적으로 핸들러를 gated 할 수도 있음).

dependencies = [] 
    for field in cls._meta.local_fields: 
     while isinstance(field, (models.OneToOneField, models.ForeignKey)): 
      if isinstance(field.rel.to,basestring): 
       dependencies.append(get_canonical(cls,field.rel.to)) 
       break 
      else: 
       field = field.rel.get_related_field() 

    def _contribute(sender, **kwargs): 
     key = (sender._meta.app_label, sender.__name__) 
     if key in dependencies: 
      dependencies.remove(key) 
     if not dependencies: 
      models.signals.class_prepared.disconnect(_contribute) 
      model = create_audit_model(cls) 

    models.signals.class_prepared.connect(_contribute, weak=False) 
관련 문제