2009-08-26 32 views
1

我一直在試圖修改AuditTrail代碼,因此它不會複製ForeignKey領域,而是拷貝相關領域(即我不想對我的數據庫表的外鍵審計模型)。Django的:審計跟蹤和懶惰的關係

我寫了一個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信號)此代碼運行。

然而,這個過程中遇到問題時,ForeignKey是有關在尚未準備尚未模型的領域中 - get_related_field()調用將失敗,因爲field.rel.to是包含了相關模型的名稱的字符串,而不是模型實例。

我不知道該如何解決此問題。在開始複製字段之前,我是否必須確定模型具有哪些依賴關係,並等待它們全部做好準備?任何關於最佳方式的想法?

回答

0

我最終什麼事做的是列出所有依賴的模型有(通過確定canoncial應用程序/名稱對;複製從django.db.models.fields.related一些代碼,以確定此)和修改我的class_prepared信號處理程序以偵聽所有車型,而不是隻是我的目標模型。

當處理程序在我的依賴項列表中識別出模型時,它會從列表中刪除它並檢查列表是否爲空;如果是,則可以創建審計模型。重要的注意事項是在創建模型之前斷開class_prepared處理程序,否則我遇到了無限遞歸(或者我可能更具體地處理了處理程序)。

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)