2011-08-03 30 views
8

我有2個應用程序像這樣的Django項目:避免循環模型進口在Django應用

## tags app, models.py 
class Tag(models.Model): 
    title = models.CharField(max_length=50) 


## items app, models.py 
from application.tags.models import Tag 

class Item(models.Model): 
    title = models.CharField(max_length=300) 
    tags = models.ManyToManyField(Tag, related_name="items") 

UPDATE澄清功能定位

我有另一種模型的方法在items.models它得到所有具有一組標籤的項目。

所得查詢是這樣的:

## Gets all of the items that have tags t1 and t2 
Item.objects.filter(tags=t1).filter(tags=t2) 

此方法使用Item模型以及所述Tag模型,這是確定的,因爲標籤被導入到項目的應用程序。

但是,我想要在標記應用程序中訪問此方法,但這樣做會導致循環導入。

現在我的解決方法是在標記應用程序中使用一組標記獲取所有項目的方法是在多對多字段中的反向關係上執行一組交集。

## Get all items that have the tags with ids tag_ids 
item_set = set(Tag.objects.get(pk=tag_ids[0]).items.all()) 
for cur_tag_id in tag_ids[1:]: ## for all of the rest of the tags 
    item_set = item_set & set(Tag.objects.get(pk=cur_tag_id).items.all()) 

這會導致多個查詢和一組交集。有沒有一種方法可以在標記應用中的Tag模型中執行類似Item.objects.filter(tags=t1).filter(tags=t2)...的操作?

我能夠解決這個問題,使用contenttypes來獲得Item模型來做出相同的查詢。這是可以接受的,還是有更好的方法來組織這些代碼?

+0

你還沒有真正給出所有的相關信息。您的過濾方法在哪裏定義?爲什麼你不能把它放在兩個應用程序可以導入的地方? –

+0

這就是我想解決的問題。它是項目應用程序中不同模型的一種方法。問題是items.models導入Tag,如果這個方法是在另一個地方,它仍然需要導入Item和Tag。然後Tag不能導入它,否則它仍然是循環的。 – jkeesh

回答

23

當你定義模型與外鍵,您可以使用以下格式:

tags = models.ManyToManyField('tags.Tag', ...) 

這意味着你不需要有進口標籤類,剛安裝的標籤應用。

然後你可以在一個不同的位置存儲一個函數,它可以導入標籤和項目,而不必擔心循環導入。

+0

謝謝。這有助於解決問題,但問題在於,如果我想從兩個應用程序的模型中的其他位置使用該功能,那麼我仍然可以獲得循環導入。 – jkeesh

+9

您可以使用django.db.models.get_model('app.Model')獲取對模型的引用,而無需導入它。這有幫助嗎? –

+1

就是這樣!我需要做get_model('app','Model'),但是工作。以這種方式檢索模型是不好的做法嗎? – jkeesh