Django отличает набор запросов от значений набора запросов - PullRequest
0 голосов
/ 07 февраля 2019

У меня есть User, который может иметь несколько Account с.На каждом Account может быть несколько Unit с.Я создаю словарь фильтра и получаю соответствующие единицы:

units = Unit.objects.filter(**unit_filter)

Однако я также хотел бы получить отдельных пользователей.Я могу легко получить их идентификаторы:

user_dicts = units.values('account__user').distinct()

или, если быть более точным:

user_ids = [rec.get('account__user') for rec in 
            units.values('account__user').distinct()]

Итак, я могу фильтровать пользователей, используя User.objects.filter(id__in=user_ids).(Я также могу использовать выражение генератора вместо понимания списка, но это не главное.)

Я не уверен, но оценка id in кажется мне не очень эффективной.Есть ли лучший способ, как получить уникальных пользователей из отфильтрованных единиц?


Редактировать:

Я добавляю SQL-запросы (не проверял их, может быть не так), чтобы сделать очевидным то, что япытаюсь сделать в Django ORM.На самом деле я пытаюсь использовать JOIN вместо WHERE предложения.

Я надеюсь на это:

WITH selected_units AS
  (SELECT id, account_id FROM units)
SELECT DISTINCT u.id FROM user u 
  JOIN account a on a.user_id=u.id
  JOIN unit ut ON ut.account=a.id 
  JOIN selected_units s ON s.id=ut.id;

Но с id_in я получаю это:

WITH selected_units AS
  (SELECT id, account_id FROM units)
SELECT DISTINCT u.id FROM user u 
  JOIN account a on a.user_id=u.id 
  JOIN unit ut ON ut.account_id=a.id 
WHERE ut.id IN (SELECT id FROM selected_units);

1 Ответ

0 голосов
/ 08 февраля 2019

Я думаю, что вы можете сделать это, используя подзапросы, что-то вроде этого:

User.objects.filter(account__unit__in=units)

Или менее симпатично:

User.objects.filter(id__in=units.values_list('account__user__id', flat=True))
...