我试图在遍历多个映射表时预取并选择相关的一些外键模型。但是我仍然遇到500多个查询,我设法将其从1000下调,但它看起来并不像子网字段被提取。
我试过以下内容:
circuits = SiteCircuits.objects.all() \
.exclude(circuit__decommissioned=True) \
.select_related('site') \
.select_related('circuit') \
.prefetch_related(
Prefetch(
'circuit__devicecircuitsubnets_set',
queryset=DeviceCircuitSubnets.objects.all() \
.select_related('subnet')
)
) \
.prefetch_related('circuit__circuitnotes_set') \
.prefetch_related('circuit__circuit_type') \
.prefetch_related('circuit__circuitfile') \
.prefetch_related('circuit__service_provider') \
.prefetch_related('circuit__circuit_type')
这样也是:
circuits = SiteCircuits.objects.all() \
.exclude(circuit__decommissioned=True) \
.select_related('site') \
.select_related('circuit') \
.prefetch_related('circuit__devicecircuitsubnets_set') \
.prefetch_related('circuit__devicecircuitsubnets_set__subnet') \
.prefetch_related('circuit__circuitnotes_set') \
.prefetch_related('circuit__circuit_type') \
.prefetch_related('circuit__circuitfile') \
.prefetch_related('circuit__service_provider') \
.prefetch_related('circuit__circuit_type')
但我在下面有500多个查询,我认为通过选择子网上的相关内容我会得到:
SELECT "config_devicecircuitsubnets"."id", "config_devicecircuitsubnets"."device_id", "config_devicecircuitsubnets"."circuit_id", "config_devicecircuitsubnets"."subnet_id", "circuits_circuit"."id", "circuits_circuit"."name", "circuits_circuit"."order_no", "circuits_circuit"."ref_no", "circuits_circuit"."expected_install_date", "circuits_circuit"."install_date", "circuits_circuit"."circuit_type_id", "circuits_circuit"."preference", "circuits_circuit"."service_provider_id", "circuits_circuit"."username", "circuits_circuit"."password", "circuits_circuit"."tel_no", "circuits_circuit"."cost_per_month", "circuits_circuit"."contract_length", "circuits_circuit"."speed_down", "circuits_circuit"."speed_up", "circuits_circuit"."rssi", "circuits_circuit"."bearer", "circuits_circuit"."decommissioned", "config_subnet"."id", "config_subnet"."subnet", "config_subnet"."mask", "config_subnet"."subnet_type_id" FROM "config_devicecircuitsubnets" INNER JOIN "circuits_circuit" ON ("config_devicecircuitsubnets"."circuit_id" = "circuits_circuit"."id") INNER JOIN "config_subnet" ON ("config_devicecircuitsubnets"."subnet_id" = "config_subnet"."id") WHERE "config_devicecircuitsubnets"."circuit_id" = '1' ORDER BY "config_devicecircuitsubnets"."id" ASC LIMIT 1
Duplicated 526 times.
行错误:
{{ item.circuit.devicecircuitsubnets_set.first.subnet }}{{ item.circuit.devicecircuitsubnets_set.first.mask }}
高级模特:
-Site
-Circuit
-Device
-Subnet
--SiteCircuits (mapping table)
--DeviceCircuitSubnets (mapping table)
编辑:
我试过一个没有抛出任何错误的子查询,但我不确定它是否正确或如何访问该字段?
子查询示例:
circuit_subnet = DeviceCircuitSubnets.objects.filter(circuit=OuterRef('pk'))
circuits = SiteCircuits.objects.all() \
.exclude(circuit__decommissioned=True) \
.select_related('site') \
.select_related('circuit') \
.prefetch_related('circuit__devicecircuitsubnets_set') \
.prefetch_related('circuit__devicecircuitsubnets_set__subnet') \
.prefetch_related('circuit__circuitnotes_set') \
.prefetch_related('circuit__circuit_type') \
.prefetch_related('circuit__circuitfile') \
.prefetch_related('circuit__service_provider') \
.prefetch_related('circuit__circuit_type') \
.annotate(circuit__devicecircuitsubnets_set=Subquery(circuit_subnet.values('subnet')[:1]))
答案 0 :(得分:1)
使用.first
可能会导致其他查询。请尝试使用.0
。
{{ item.circuit.devicecircuitsubnets_set.first.subnet }}{{ item.circuit.devicecircuitsubnets_set.first.mask }}
如果您只需要预取第一个相关项目,那么您可以使用subquery。