2016-10-12 46 views
2

我有一個普通的Django模型,它具有與Django多態模型的ForeignKey關係。在與django多態模型的子類的關係上過濾純模型?

讓我們把具有content ForeignKey的領域多態Content模型亞型VideoAudio(簡化的示例)第一PlainModel

現在我想要查詢涉及Video的所有PlainModel實例。

問題是我發現的所有文檔都是關於通過多態模型本身直接過濾的。所以在這個例子中就像Content.objects.instance_of(Video)。但我需要PlainModel的,所以它需要看起來像PlainModel.objects.filter(content__instance_of=Video)。我嘗試了一堆變體,但我找不到任何可行的方法。

在文檔中,他們使用Q(instance_of=ModelB),但這不適用於關係Q(content__instance_of=ModelB)。它給出了一個錯誤,如'不能查詢「x」:必須是「y」實例。'即使翻譯調用,我猜是因爲PlainModel不是多態感知。

我有一個臨時黑客,它使用像PlainModel.objects.filter(content__polymorphic_ctype_id=my_content_type_id)這樣的常規django過濾器直接過濾polymorphic_ctype字段,但這不處理子類。例如:尋找Video時將不會找到ExtendedVideo,因爲它會有不同的ContentType標識。

我可以去解決這個問題,並保留允許的子類型列表或解析類型層次結構,以獲得過濾器的更多內容類型,但似乎從django-polymorphic複製功能。

回答

0

可以通過先獲得所有PlainModel實例有一個Video亞型,然後查詢是在查詢集的外鍵關係做到這一點:

content_videos = Content.objects.instance_of(Video) 
plain_model_videos = PlainModel.objects.filter(content__in=content_videos) 

請參閱the docs以供參考。

+0

好主意,但我得看看這個執行的SQL,看看這是否可以接受。 IIRC有關於查詢集的一些內容是'__in'子句。 – Bartvds

+0

@Bartvds這不是特定於Django Polymorphic,因爲我們知道第一個查詢可以獲得第二個查詢所需的id。參考文檔中的SQL查詢更新了我的答案。 – YPCrumble

+0

當然,但我希望使用JOIN的解決方案(通過Django Polymorphic或直接通過ORM);作爲文檔說明,子查詢的表現並不是很好,特別是在像我們這樣的大型表格中。但我認爲我們需要進行基準測試,看看這是否已經可以接受。 – Bartvds