Должен быть способ выполнить этот запрос через ORM, но я его не вижу.
Вот что я моделирую: один арендатор может занимать несколько комнат и один Пользователь может владеть несколькими комнатами. Таким образом, у комнат есть FK для арендатора и FK для пользователя. Комнаты также обслуживаются (возможно, отдельным) пользователем.
То есть у меня есть эти (упрощенные) модели:
class Tenant(models.Model):
name = models.CharField(max_length=100)
class Room(models.Model):
owner = models.ForeignKey(User)
maintainer = models.ForeignKey(User)
tenant = models.ForeignKey(Tenant)
Учитывая арендатора, я хочу, чтобы пользователи владели комнатой, которую они занимают.
Соответствующий запрос SQL будет следующим:
SELECT auth_user.id, ...
FROM tenants_tenant, tenants_room, auth_user
WHERE tenants_tenant.id = tenants_room.tenant_id
AND tenants_room.owner_id = auth_user.id;
Получение любого индивидуального значения из связанных объектов пользователя может быть выполнено с помощью, например, my_tenant.rooms.values_list ('owner__email', flat = True)
, но получение полного набора запросов пользователей сбивает меня с толку.
Обычно одним из способов решения этой проблемы является настройка поле ManyToMany
в моей модели Tenant
, указывающее на пользователя
с TenantRoom
в качестве сквозной модели. Однако в данном случае это не сработает, поскольку модель TenantRoom
имеет второго (несвязанного) ForeignKey
- пользователя
( см. «Ограничения» ). Кроме того, это кажется ненужным беспорядком в модели арендатора.
Выполнение my_tenant.rooms.values_list ('user', flat = True)
приближает меня, но возвращает ValuesListQuerySet идентификаторов пользователей, а не набор запросов фактических объектов User.
Итак: есть ли способ получить набор запросов фактических экземпляров модели через ORM, используя всего один запрос?
Изменить
Если на самом деле нет способа сделать это напрямую в одном запросе через ORM, какой лучший (какая-то комбинация наиболее производительного, наиболее идиоматического, наиболее читаемого и т. д.) способа выполнить то, что я ищу? Вот варианты, которые я вижу:
Подвыбор
users = User.objects.filter (id__in = my_tenant.rooms.values_list ('user')) flat = True)
приближает меня, но возвращает ValuesListQuerySet идентификаторов пользователей, а не набор запросов фактических объектов User.Вопрос
Итак: есть ли способ получить набор запросов фактических экземпляров модели через ORM, используя только один запрос?
Изменить
Если на самом деле нет способа сделать это напрямую в одном запросе через ORM, какой лучший (какая-то комбинация наиболее производительного, наиболее идиоматического, наиболее читаемого и т. д.) способа выполнить то, что я ищу? Вот варианты, которые я вижу:
Подвыбор
users = User.objects.filter (id__in = my_tenant.rooms.values_list ('user')) flat = True)
приближает меня, но возвращает ValuesListQuerySet идентификаторов пользователей, а не набор запросов фактических объектов User.Вопрос
Итак: есть ли способ получить набор запросов фактических экземпляров модели через ORM, используя всего один запрос?
Изменить
Если на самом деле нет способа сделать это напрямую в одном запросе через ORM, какой лучший (какая-то комбинация наиболее производительного, наиболее идиоматического, наиболее читаемого и т. д.) способа выполнить то, что я ищу? Вот варианты, которые я вижу:
Подвыбор
users = User.objects.filter (id__in = my_tenant.rooms.values_list ('user')) используя только один запрос?
Edit
Если на самом деле нет способа сделать это напрямую в одном запросе через ORM, что лучше (какая-то комбинация наиболее производительного, наиболее идиоматического, наиболее читаемого и т. д. .) способ выполнить то, что я ищу? Вот варианты, которые я вижу:
Подвыбор
users = User.objects.filter (id__in = my_tenant.rooms.values_list ('user')) используя только один запрос?
Edit
Если на самом деле нет способа сделать это напрямую в одном запросе через ORM, что лучше (какая-то комбинация наиболее производительного, наиболее идиоматического, наиболее читаемого и т. д. .) способ выполнить то, что я ищу? Вот варианты, которые я вижу:
Подвыбор
users = User.objects.filter (id__in = my_tenant.rooms.values_list ('user'))
Подвыбор с помощью Python (см. Рекомендации по производительности для объяснения этого)
user_ids = id__in = my_tenant.rooms.values_list ('user') users = User.objects.filter (id__in = list (user_ids))
Необработанный SQL:
User.objects.all ("" "SELECT auth_user. * ОТ tenants_tenant, tenants_room, auth_user ГДЕ tenants_tenant.id = tenants_room.tenant_id И tenants_room.owner_id = auth_user.id "" ")
Другое ...?