2016-11-23 46 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,所以您可以放心,它可以按照您的预期工作。