2011-04-15 88 views
2

我跟隨此帖子here並列出了如何將一個模型的ForeignKey設置爲另一個應用程序中的模型。但是,當我第二次嘗試時出現錯誤,並不確定原因。Django從另一個應用程序模型中的外鍵導入錯誤

我有一個'項目'和'註釋'模型的中央應用程序,以及報告模型的報告應用程序。一個「註釋」的FK在報表應用了「報告」,這似乎做工精細與此代碼:

#models.py for Central app 
from GIanno.pt_reports.models import Report 

class annotation(models.Model): 
    ... 
    report=models.ForeignKey(Report) 

但是,報告中的應用程序,當我嘗試設置FK爲'report'將其與'Central'應用程序中的'項目'關聯起來,使用上述相同的格式,我會從導入行中看到一個錯誤「無法導入名稱'項目'

。一種方式,而不是其他是否爲了莫名其妙沒關係感謝

回答

5

我的猜測是,你已經創建了一個圓形進口的狀況。當你從一個python模塊導入某些東西時,會發生這種情況,然後從試圖導入模塊的模塊導入它,從而阻止導入進行解析。

一般有三種策略應對進口的圓形,其中兩個將在這種情況下工作:你的類各地

  1. 移動和進口,使進口只能走一個方向。

  2. 使用懶惰評估。在Django的情況下,可以通過使用點符號傳遞指定應用程序名稱和模型的字符串來實現ForeignKey:report=models.ForeignKey('central.Report')

  3. 將導入語句移出全局模塊範圍並移入模塊中的函數範圍。通過這種方式,不會立即評估導入,並且模塊可以作爲一個整體成功導入,同時仍允許在調用模塊時導入模塊。 (注:這不會對ForeignKey的關係的工作)

懶惰FK分辨率(#2)可能是這裏最好的選擇。總的來說,儘管最好的策略是簡化模型/模塊安排,以儘可能避免循環導入。

1

嘗試:?

class annotation(models.Model): 
    ... 
    report=models.ForeignKey('centralapp.Report') 

用中央應用程序名稱的名稱替換'centralapp',而無需導入。

Lazy Relationships

0

懶惰關係可能有用的另一種情況是使用導入順序。這不是一個循環引用(它不能分辨誰在先),而是一個代碼在另一個代碼之前加載的情況。

例如,假設我有Doc模型和Log模型。 Log模型具有用於Doc的FK,因此我可以在文檔中記錄更改。這工作正常,直到,我們假設,我嘗試在我的Doc模型的保存方法中生成日誌記錄(以創建保存事件日誌條目)。在這種情況下,Doc對象中沒有Log PK,但是也有類似的問題。

在這種情況下,你會得到一個導入順序問題,其中一個人會嘗試引用一些尚未載入Python的東西。它與循環引用類似,但是具有不同的原因。

這可以通過其他方式解決,但是您會遇到此問題的另一個示例。

相關問題