Просмотр исходного кода

Merge pull request #22157 from netbox-community/22061-graphql-hints

Closes #22061: Add prefetch hints for GraphQL types
bctiemann 1 неделя назад
Родитель
Сommit
b2a1e94508

+ 2 - 2
netbox/circuits/graphql/types.py

@@ -74,7 +74,7 @@ class ProviderNetworkType(PrimaryObjectType):
 class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, ObjectType):
 class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, ObjectType):
     circuit: Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]
     circuit: Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='termination')
     def termination(self) -> Annotated[
     def termination(self) -> Annotated[
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
@@ -133,7 +133,7 @@ class CircuitGroupType(OrganizationalObjectType):
 class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
 class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
     group: Annotated['CircuitGroupType', strawberry.lazy('circuits.graphql.types')]
     group: Annotated['CircuitGroupType', strawberry.lazy('circuits.graphql.types')]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='member')
     def member(self) -> Annotated[
     def member(self) -> Annotated[
         Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]
         Annotated['CircuitType', strawberry.lazy('circuits.graphql.types')]
         | Annotated['VirtualCircuitType', strawberry.lazy('circuits.graphql.types')],
         | Annotated['VirtualCircuitType', strawberry.lazy('circuits.graphql.types')],

+ 55 - 16
netbox/dcim/graphql/types.py

@@ -4,6 +4,7 @@ import strawberry
 import strawberry_django
 import strawberry_django
 from django.db.models import Func, IntegerField
 from django.db.models import Func, IntegerField
 
 
+from circuits.models import CircuitTermination
 from core.graphql.mixins import ChangelogMixin
 from core.graphql.mixins import ChangelogMixin
 from dcim import models
 from dcim import models
 from extras.graphql.mixins import ConfigContextMixin, ContactsMixin, ImageAttachmentsMixin
 from extras.graphql.mixins import ConfigContextMixin, ContactsMixin, ImageAttachmentsMixin
@@ -17,6 +18,8 @@ from netbox.graphql.types import (
     PrimaryObjectType,
     PrimaryObjectType,
 )
 )
 from users.graphql.mixins import OwnerMixin
 from users.graphql.mixins import OwnerMixin
+from utilities.querysets import RestrictedPrefetch
+from virtualization.models import Cluster
 
 
 from .filters import *
 from .filters import *
 from .mixins import CabledObjectMixin, PathEndpointMixin
 from .mixins import CabledObjectMixin, PathEndpointMixin
@@ -288,11 +291,11 @@ class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, Prima
     inventoryitems: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]]
     inventoryitems: list[Annotated["InventoryItemType", strawberry.lazy('dcim.graphql.types')]]
     vdcs: list[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]]
     vdcs: list[Annotated["VirtualDeviceContextType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='vc_master_for')
     def vc_master_for(self) -> Annotated["VirtualChassisType", strawberry.lazy('dcim.graphql.types')] | None:
     def vc_master_for(self) -> Annotated["VirtualChassisType", strawberry.lazy('dcim.graphql.types')] | None:
         return self.vc_master_for if hasattr(self, 'vc_master_for') else None
         return self.vc_master_for if hasattr(self, 'vc_master_for') else None
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent_bay')
     def parent_bay(self) -> Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')] | None:
     def parent_bay(self) -> Annotated["DeviceBayType", strawberry.lazy('dcim.graphql.types')] | None:
         return self.parent_bay if hasattr(self, 'parent_bay') else None
         return self.parent_bay if hasattr(self, 'parent_bay') else None
 
 
@@ -327,7 +330,7 @@ class InventoryItemTemplateType(ComponentTemplateType):
     role: Annotated['InventoryItemRoleType', strawberry.lazy('dcim.graphql.types')] | None
     role: Annotated['InventoryItemRoleType', strawberry.lazy('dcim.graphql.types')] | None
     manufacturer: Annotated['ManufacturerType', strawberry.lazy('dcim.graphql.types')]
     manufacturer: Annotated['ManufacturerType', strawberry.lazy('dcim.graphql.types')]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent')
     def parent(self) -> Annotated['InventoryItemTemplateType', strawberry.lazy('dcim.graphql.types')] | None:
     def parent(self) -> Annotated['InventoryItemTemplateType', strawberry.lazy('dcim.graphql.types')] | None:
         return self.parent
         return self.parent
 
 
@@ -430,7 +433,7 @@ class FrontPortTemplateType(ModularComponentTemplateType):
 class MACAddressType(PrimaryObjectType):
 class MACAddressType(PrimaryObjectType):
     mac_address: str
     mac_address: str
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='assigned_object')
     def assigned_object(self) -> Annotated[
     def assigned_object(self) -> Annotated[
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
         | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
@@ -494,7 +497,7 @@ class InventoryItemType(ComponentType):
 
 
     child_items: list[Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')]]
     child_items: list[Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent')
     def parent(self) -> Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')] | None:
     def parent(self) -> Annotated['InventoryItemType', strawberry.lazy('dcim.graphql.types')] | None:
         return self.parent
         return self.parent
 
 
@@ -541,11 +544,20 @@ class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, Nested
     devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
     devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["LocationType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
+        ),
+    )
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
         return self.cluster_set.all()
         return self.cluster_set.all()
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'circuit_terminations', info.context.request.user, 'view',
+            queryset=CircuitTermination.objects.all()
+        ),
+    )
     def circuit_terminations(self) -> list[
     def circuit_terminations(self) -> list[
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
     ]:
     ]:
@@ -599,7 +611,7 @@ class ModuleBayType(ModularComponentType):
     installed_module: Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')] | None
     installed_module: Annotated["ModuleType", strawberry.lazy('dcim.graphql.types')] | None
     children: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent')
     def parent(self) -> Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')] | None:
     def parent(self) -> Annotated["ModuleBayType", strawberry.lazy('dcim.graphql.types')] | None:
         return self.parent
         return self.parent
 
 
@@ -864,15 +876,24 @@ class RegionType(VLANGroupsMixin, ContactsMixin, NestedGroupObjectType):
     sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
     sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["RegionType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent')
     def parent(self) -> Annotated["RegionType", strawberry.lazy('dcim.graphql.types')] | None:
     def parent(self) -> Annotated["RegionType", strawberry.lazy('dcim.graphql.types')] | None:
         return self.parent
         return self.parent
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
+        ),
+    )
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
         return self.cluster_set.all()
         return self.cluster_set.all()
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'circuit_terminations', info.context.request.user, 'view',
+            queryset=CircuitTermination.objects.all()
+        ),
+    )
     def circuit_terminations(self) -> list[
     def circuit_terminations(self) -> list[
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
     ]:
     ]:
@@ -903,11 +924,20 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, PrimaryObj
     clusters: list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]
     clusters: list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]
     vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
     vlans: list[Annotated["VLANType", strawberry.lazy('ipam.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
+        ),
+    )
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
         return self.cluster_set.all()
         return self.cluster_set.all()
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'circuit_terminations', info.context.request.user, 'view',
+            queryset=CircuitTermination.objects.all()
+        ),
+    )
     def circuit_terminations(self) -> list[
     def circuit_terminations(self) -> list[
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
     ]:
     ]:
@@ -925,15 +955,24 @@ class SiteGroupType(VLANGroupsMixin, ContactsMixin, NestedGroupObjectType):
     sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
     sites: list[Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]]
     children: list[Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent')
     def parent(self) -> Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')] | None:
     def parent(self) -> Annotated["SiteGroupType", strawberry.lazy('dcim.graphql.types')] | None:
         return self.parent
         return self.parent
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'cluster_set', info.context.request.user, 'view', queryset=Cluster.objects.all()
+        ),
+    )
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
     def clusters(self) -> list[Annotated["ClusterType", strawberry.lazy('virtualization.graphql.types')]]:
         return self.cluster_set.all()
         return self.cluster_set.all()
 
 
-    @strawberry_django.field
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'circuit_terminations', info.context.request.user, 'view',
+            queryset=CircuitTermination.objects.all()
+        ),
+    )
     def circuit_terminations(self) -> list[
     def circuit_terminations(self) -> list[
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
         Annotated["CircuitTerminationType", strawberry.lazy('circuits.graphql.types')]
     ]:
     ]:

+ 16 - 5
netbox/extras/graphql/mixins.py

@@ -4,6 +4,9 @@ import strawberry
 import strawberry_django
 import strawberry_django
 from strawberry.types import Info
 from strawberry.types import Info
 
 
+from extras.models import ImageAttachment, JournalEntry
+from utilities.querysets import RestrictedPrefetch
+
 __all__ = (
 __all__ = (
     'ConfigContextMixin',
     'ConfigContextMixin',
     'ContactsMixin',
     'ContactsMixin',
@@ -50,16 +53,24 @@ class CustomFieldsMixin:
 @strawberry.type
 @strawberry.type
 class ImageAttachmentsMixin:
 class ImageAttachmentsMixin:
 
 
-    @strawberry_django.field
-    def image_attachments(self, info: Info) -> list[Annotated['ImageAttachmentType', strawberry.lazy('.types')]]:
-        return self.images.restrict(info.context.request.user, 'view')
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'images', info.context.request.user, 'view', queryset=ImageAttachment.objects.all()
+        ),
+    )
+    def image_attachments(self) -> list[Annotated['ImageAttachmentType', strawberry.lazy('.types')]]:
+        return self.images.all()
 
 
 
 
 @strawberry.type
 @strawberry.type
 class JournalEntriesMixin:
 class JournalEntriesMixin:
 
 
-    @strawberry_django.field
-    def journal_entries(self, info: Info) -> list[Annotated['JournalEntryType', strawberry.lazy('.types')]]:
+    @strawberry_django.field(
+        prefetch_related=lambda info: RestrictedPrefetch(
+            'journal_entries', info.context.request.user, 'view', queryset=JournalEntry.objects.all()
+        ),
+    )
+    def journal_entries(self) -> list[Annotated['JournalEntryType', strawberry.lazy('.types')]]:
         return self.journal_entries.all()
         return self.journal_entries.all()
 
 
 
 

+ 6 - 6
netbox/ipam/graphql/types.py

@@ -128,7 +128,7 @@ class FHRPGroupType(IPAddressesMixin, PrimaryObjectType):
 class FHRPGroupAssignmentType(BaseObjectType):
 class FHRPGroupAssignmentType(BaseObjectType):
     group: Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
     group: Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='interface')
     def interface(self) -> Annotated[
     def interface(self) -> Annotated[
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
         | Annotated['VMInterfaceType', strawberry.lazy('virtualization.graphql.types')],
@@ -153,7 +153,7 @@ class IPAddressType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
     tunnel_terminations: list[Annotated['TunnelTerminationType', strawberry.lazy('vpn.graphql.types')]]
     tunnel_terminations: list[Annotated['TunnelTerminationType', strawberry.lazy('vpn.graphql.types')]]
     services: list[Annotated['ServiceType', strawberry.lazy('ipam.graphql.types')]]
     services: list[Annotated['ServiceType', strawberry.lazy('ipam.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='assigned_object')
     def assigned_object(self) -> Annotated[
     def assigned_object(self) -> Annotated[
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
         | Annotated['FHRPGroupType', strawberry.lazy('ipam.graphql.types')]
@@ -190,7 +190,7 @@ class PrefixType(ContactsMixin, BaseIPAddressFamilyType, PrimaryObjectType):
     vlan: Annotated['VLANType', strawberry.lazy('ipam.graphql.types')] | None
     vlan: Annotated['VLANType', strawberry.lazy('ipam.graphql.types')] | None
     role: Annotated['RoleType', strawberry.lazy('ipam.graphql.types')] | None
     role: Annotated['RoleType', strawberry.lazy('ipam.graphql.types')] | None
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='scope')
     def scope(self) -> Annotated[
     def scope(self) -> Annotated[
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
@@ -252,7 +252,7 @@ class ServiceType(ContactsMixin, PrimaryObjectType):
     ports: list[int]
     ports: list[int]
     ipaddresses: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
     ipaddresses: list[Annotated['IPAddressType', strawberry.lazy('ipam.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='parent')
     def parent(self) -> Annotated[
     def parent(self) -> Annotated[
         Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]
         Annotated['DeviceType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]
         | Annotated['VirtualMachineType', strawberry.lazy('virtualization.graphql.types')]
@@ -291,7 +291,7 @@ class VLANType(PrimaryObjectType):
     interfaces_as_tagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
     interfaces_as_tagged: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
     vminterfaces_as_tagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
     vminterfaces_as_tagged: list[Annotated["VMInterfaceType", strawberry.lazy('virtualization.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='qinq_svlan')
     def qinq_svlan(self) -> Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None:
     def qinq_svlan(self) -> Annotated["VLANType", strawberry.lazy('ipam.graphql.types')] | None:
         return self.qinq_svlan
         return self.qinq_svlan
 
 
@@ -309,7 +309,7 @@ class VLANGroupType(OrganizationalObjectType):
     total_vlan_ids: BigInt
     total_vlan_ids: BigInt
     tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
     tenant: Annotated['TenantType', strawberry.lazy('tenancy.graphql.types')] | None
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='scope')
     def scope(self) -> Annotated[
     def scope(self) -> Annotated[
         Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]
         Annotated['ClusterType', strawberry.lazy('virtualization.graphql.types')]
         | Annotated['ClusterGroupType', strawberry.lazy('virtualization.graphql.types')]
         | Annotated['ClusterGroupType', strawberry.lazy('virtualization.graphql.types')]

+ 1 - 1
netbox/virtualization/graphql/types.py

@@ -59,7 +59,7 @@ class ClusterType(ContactsMixin, VLANGroupsMixin, PrimaryObjectType):
     virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
     virtual_machines: list[Annotated["VirtualMachineType", strawberry.lazy('virtualization.graphql.types')]]
     devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
     devices: list[Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='scope')
     def scope(self) -> Annotated[
     def scope(self) -> Annotated[
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]

+ 1 - 1
netbox/vpn/graphql/types.py

@@ -145,7 +145,7 @@ class L2VPNType(ContactsMixin, PrimaryObjectType):
 class L2VPNTerminationType(NetBoxObjectType):
 class L2VPNTerminationType(NetBoxObjectType):
     l2vpn: Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]
     l2vpn: Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='assigned_object')
     def assigned_object(self) -> Annotated[
     def assigned_object(self) -> Annotated[
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         Annotated['InterfaceType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['VLANType', strawberry.lazy('ipam.graphql.types')]
         | Annotated['VLANType', strawberry.lazy('ipam.graphql.types')]

+ 1 - 1
netbox/wireless/graphql/types.py

@@ -46,7 +46,7 @@ class WirelessLANType(PrimaryObjectType):
 
 
     interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
     interfaces: list[Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]]
 
 
-    @strawberry_django.field
+    @strawberry_django.field(prefetch_related='scope')
     def scope(self) -> Annotated[
     def scope(self) -> Annotated[
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         Annotated['LocationType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]
         | Annotated['RegionType', strawberry.lazy('dcim.graphql.types')]