Я попробовал это с 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
LEFT
в LEFT OUTER JOIN
гарантирует, что вы получите записи из A, даже если нет совпадающих записей в B. И поскольку Django не сохранит B с NULL
id, вы можете быть уверены, что он будет работать так, как вы ожидаете.
Я не могу придумать причины, по которым это не сработает, [Этот вопрос] (http://stackoverflow.com/q/21405658/1324033) кажется, что он правильный – Sayse