我總是發現Django orm對子類化模型的處理非常漂亮。這可能就是爲什麼我遇到像這樣的問題。django orm - 如何在超類的子類的外鍵上使用select_related()
採取三種模式:
class A(models.Model):
field1 = models.CharField(max_length=255)
class B(A):
fk_field = models.ForeignKey('C')
class C(models.Model):
field2 = models.CharField(max_length=255)
所以,現在你可以查詢A
模型,並得到所有的B
模型,其中可供選擇:
the_as = A.objects.all()
for a in the_as:
print a.b.fk_field.field2 #Note that this throws an error if there is no B record
這裏的問題是,你正在尋找大量的數據庫調用來檢索所有的數據。
現在假設您想要檢索數據庫中所有A
模型的查詢集,但也包含所有子類記錄和子類的外鍵記錄,並使用select_related()
將應用程序限制爲單個數據庫調用。你會寫這樣的查詢:
the_as = A.objects.select_related("b", "b__fk_field").all()
一個查詢返回所有需要的數據!真棒。
除外。由於這個版本的查詢是做自己的過濾,即使select_related
是不應該在所有篩選的結果:
set_1 = A.objects.select_related("b", "b__fk_field").all() #Only returns A objects with associated B objects
set_2 = A.objects.all() #Returns all A objects
len(set_1) > len(set_2) #Will always be False
我使用的Django的調試工具來檢查查詢和發現問題。生成的SQL查詢使用INNER JOIN
加入C
表來查詢,而不是LEFT OUTER JOIN
像其他子類領域:
SELECT "app_a"."field1", "app_b"."fk_field_id", "app_c"."field2"
FROM "app_a"
LEFT OUTER JOIN "app_b" ON ("app_a"."id" = "app_b"."a_ptr_id")
INNER JOIN "app_c" ON ("app_b"."fk_field_id" = "app_c"."id");
而且似乎如果我簡單地改變INNER JOIN
到LEFT OUTER JOIN
,然後我得到的記載,我想要,但是這在使用Django的ORM時無濟於事。
這是一個在Django的ORM中的select_related()
中的錯誤?有沒有解決這個問題的方法,或者我只需要直接查詢數據庫並自己映射結果呢?我應該使用像Django-Polymorphic這樣的東西嗎?
這是一個尚未解決的問題嗎? – ilse2005