2016-11-23 95 views
2

我正在嘗試查詢表中沒有來自其他模型的反向引用的所有對象。在Django反向引用上過濾

class A(models.Model): 
    pass 

class B(models.Model): 
    reference = models.ForeignKey(A) 

爲了讓所有A對象,沒有引用任何B對象,我做

A.objects.filter(b__isnull=True) 

Django documentation on isnull沒有提及反向引用的。

我可以惹上麻煩嗎?還是隻是記錄不完整?

+1

我想不出一個原因,那不會工作,[這個問題](http://stackoverflow.com/q/21405658/1324033)似乎表明它是正確的 – Sayse

回答

2

我試着用Django 1.10.3,使用相同的代碼示例。

讓我們來看看原始的SQL語句的Django創建:

>>> print(A.objects.filter(b__isnull=True).query) 
SELECT "backrefs_a"."id" FROM "backrefs_a" LEFT OUTER JOIN "backrefs_b" ON ("backrefs_a"."id" = "backrefs_b"."reference_id") WHERE "backrefs_b"."id" IS NULL 

技術上講,這是不完全一樣的SQL Django會發送到數據庫,但它是足夠接近。有關詳細討論,請參閱https://stackoverflow.com/a/1074224/5044893

如果我們漂亮起來了一點,你可以看到,查詢其實是相當安全的:

SELECT "backrefs_a"."id" 
FROM "backrefs_a" 
LEFT OUTER JOIN "backrefs_b" ON ("backrefs_a"."id" = "backrefs_b"."reference_id") 
WHERE "backrefs_b"."id" IS NULL 

LEFTLEFT OUTER JOIN保證你會得到記錄從A,即使在B中沒有匹配的記錄。並且,因爲Django不會保存B的NULLID,所以您可以放心,它可以按照您的預期工作。