Использовать Django ORM для создания левого внешнего соединения между несвязанными моделями?

Предположим, у меня есть две модели:

class One(models.Model):
    name = models.CharField(max_length=300, unique=True)


class Two(models.Model):
    name = models.CharField(max_length=300, unique=True)

Они не связаны внешним ключом, и есть причины оставить их так в этом проекте.

Я хочу знать экземпляры One с name, которых нет в Two.

Вот SQL для получения этого:

select app_one.name
from app_one left join app_two on app_one.name = app_two.name
where app_two.name is null
group by 1;

Можно ли получить это через ORM, или нужно просто написать запрос?

Примечание: одно из возможных решений - запросить все имена One и использовать IN на Two. Я бы не хотел так делать, это плохо масштабируется.

Вы можете использовать Subquery:

from django.db.models import Subquery

results = One.objects.exclude(name__in=Subquery(Two.objects.values("name")))

Сгенерированный SQL будет выглядеть примерно так

SELECT "app_one"."name"
FROM "app_one"
WHERE NOT (
    "app_one"."name" IN (SELECT U0."name" FROM "app_two" U0)
        AND "app_one"."name" IS NOT NULL
    )
Вернуться на верх