Прежде всего, вы должны иметь возможность использовать .select_related("gateway")
вместо .prefetch_related("gateway")
. Это должно избавить вас от запроса.
Кажется, ваша проблема здесь:
if device.gatewaydevices.gateway
Здесь gatewaydevices
не является экземпляром одной модели, поэтому у него нет свойства шлюза . Я не совсем уверен, какой у вас вариант использования, но gatewaydevices
может быть несколько. Может быть, вам нужен первый (это не удастся, если будет ноль gatewaydevices
):
if device.gatewaydevices.first().gateway
Возможно, вы захотите узнать, есть ли какие-либо. Это должно сработать:
if device.gatewaydevices.filter(gateway__isnull=False)
Это кажется странным, но кажется, что этот код должен быть с остальной частью запроса, если вы хотите исключить объекты без gateway
s. Я думаю, вам следует полностью удалить if
и всегда возвращать данные. Вы не экономите время базы данных, делая это.
На основе дальнейшего комментария:
if device.gatewaydevices.filter(end_date__isnull=True).first()
(возможно) лучший способ написать запрос, если вы пытаетесь избежать лишних работа:
gateway_devices = (
GatewayDevice.objects
.filter(end_date_isnull=True)
.select_related("gateway", "device")
)
Это позволит получить все в одном запросе, и вы можете просто использовать простой доступ к атрибутам для получения связанных объектов без каких-либо дополнительных запросов, например:
for gateway_device in gateway_devices:
print(gateway_device.device.name)
Глядя на ваши модели (хотя я не вижу всего, что мне нужно, чтобы написать это идеально), похоже, вам также нужна информация из Device
отношений, поэтому вам может потребоваться настроить это, чтобы device
предварительно выбирал то, что вам нужно, что-то вроде :
gateway_devices = (
GatewayDevice.objects
.filter(end_date_isnull=True)
.select_related("gateway")
.prefetch_related(
Prefetch(
"device",
queryset=Device.objects.prefetch_related(
# Depending how these are related you may be able to
# save some queries using `select_related()` instead.
"site__users", "software_update_history", "supplier"
)
)
)
)
Это может быть не идеально, но должно дать вам то, что вам нужно для хорошего старта.