Skip to main content
 首页 » 编程设计

python之过滤 Django 反向引用

2024年10月17日36xiaohuochai

我正在尝试查询表中的所有对象,而无需来自另一个模型的反向引用。

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根本没有提到反向引用。

我会因此而惹上麻烦吗?还是它的文档记录不完整?

请您参考如下方法:

我用 Django 1.10.3 试过这个,使用你的相同代码示例。

让我们看一下 Django 创建的原始 SQL 语句:

>>> 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 

从技术上讲,这与 Django 将发送到数据库的 SQL 并不完全相同,但已经足够接近了。有关更多讨论,请参阅 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 

LEFT OUTER JOIN 中的 LEFT 确保您将从 A 获取记录,即使 B 中没有匹配的记录。而且,因为 Django 不会用 NULL id 保存一个 B,你可以放心,它会按你预期的那样工作。