Django orm subquery - в предложении без подстановки
Мне нужно построить запрос, используя Django ORM, который выглядит как этот запрос на SQL:
select * from A where id not in (select a_id from B where ... )
Я пытаюсь использовать такой код:
ids = B.objects.filter(...)
a_objects = A.object.exclude(id__in=Subquery(ids.values('a__id'))).all()
Проблема в том, что вместо вложенного select Django генерирует запрос, который выглядит как
select * from A where id not in (1, 2, 3, 4, 5 ....)
в пункте where in явно перечислены все идентификаторы, которые должны быть исключены, что делает результирующий sql нечитаемым при печати в журналы. Можно ли изменить этот запрос, чтобы использовался вложенный select?
Итак, я вижу, что ваша цель - получить все A, которые не имеют отношений внешних ключей с B. Если я прав, то вы можете просто использовать инверсный поиск для этого.
Итак, когда вы определяете модели таким образом:
class A:
pass
class B:
a = ForeignKey(to=a, related_name='bs')
Вы можете отфильтровать его следующим образом:
A.objects.filter(bs__isnull=True)
Кроме того, если вы не определите related_name
, по умолчанию будет установлено b_set
, так что вы сможете A.objects.filter(b_set__isnull=True)
чтобы сделать фильтр на B, вы можете
ids = B.objects.filter(x=x).values_list('id',flat=true)
вы получаете список идентификаторов, затем делаете
a_objects = A.object.exclude(id__in=ids)
как уже говорилось ранее, если существует отношение
Вам не нужно делать ничего особенного, просто используйте queryset непосредственно в вашем фильтре.
ids = B.objects.filter(...)
a_objects = A.object.exclude(id__in=ids).all()
# that should generate the subquery statement
select * from A where NOT (id in (select a_id from B where ... ))