Простое создание подзапросов в Django ORM (просто используйте QuerySet
как часть другого запроса), но возможно ли, чтобы этот подзапрос ссылался на поля в «родительском» (внешнем, основном) запросе?В подзапросе Django можно ли ссылаться на «родительский» запрос?
Полный пример того, что я пытаюсь достичь, см. В этой статье SQL Fiddle. Я разделил его на два вопроса (other one here). В этом случае у меня есть модель Whole
, которая представляет значение, которое должно быть достигнуто. Несколько Part
s вносят вклад в это с собственным (рассчитанным) значением. Я хочу получить все Whole
s с не еще не закончено (то есть total_value
отличается от суммы отдельных значений).
select w.*
from whole w
where w.total_value != (
select sum(value expression)
from part p
where p.whole_id = w.id
group by p.whole_id
);
Я не знаю, как (или если это возможно) сделать это с помощью Django ORM. Я видел manyexamples подзапросов с использованием __in
(и мог подтвердить print qs.query
, что результат действительно запущен как один запрос), но только тогда, когда оба запроса не зависят друг от друга. Здесь подзапрос ограничивается полем в родительском запросе (w.id
). Я думал об использовании F()
, Q()
или даже extra
, но не вполне может понять, что делать ...
Вот SSCCE, в случае, если кто хочет поэкспериментировать с ним: Download или Browse. Он имеет те же модели и данные, что и связанный выше SQL fiddle.
Update: для моего конкретного случая, я узнал, что нет необходимости делать подзапрос, я могу просто использовать group by
и having
(как this SQL Fiddle шоу):
q = Q(part__isnull=True) | ~Q(partial=F('total_value'))
qs = Whole.objects.annotate(partial=Sum(...)).filter(q).distinct()
# And if total_value can be zero:
qs = qs.exclude(part__isnull=True, total_value=0)
Общий случай для подзапросов все еще не решена (хотя и не используется некоторый необработанный SQL, как показывают my answer below).