Procházet zdrojové kódy

Closes #16224 GraphQL Pagination (#18903)

* 16244 add pagination

* 16244 add pagination

* 16244 fix order_by pagination

* 16224 document pagination

* 16224 remove extraneous code

* 16224 missing core types

* 16224 review changes

* 16224 review changes

* 16224 review changes
Arthur Hanson před 11 měsíci
rodič
revize
fe7cc8cae9

+ 12 - 0
docs/integrations/graphql-api.md

@@ -131,6 +131,18 @@ Certain queries can return multiple types of objects, for example cable terminat
 ```
 ```
 The field "class_type" is an easy way to distinguish what type of object it is when viewing the returned data, or when filtering.  It contains the class name, for example "CircuitTermination" or "ConsoleServerPort".
 The field "class_type" is an easy way to distinguish what type of object it is when viewing the returned data, or when filtering.  It contains the class name, for example "CircuitTermination" or "ConsoleServerPort".
 
 
+## Pagination
+
+Queries can be paginated by specifying pagination in the query and supplying an offset and optionaly a limit in the query.  If no limit is given, a default of 100 is used.  Queries are not paginated unless requested in the query. An example paginated query is shown below:
+
+```
+query {
+  device_list(pagination: { offset: 0, limit: 20 }) {
+    id
+  }
+}
+```
+
 ## Authentication
 ## Authentication
 
 
 NetBox's GraphQL API uses the same API authentication tokens as its REST API. Authentication tokens are included with requests by attaching an `Authorization` HTTP header in the following form:
 NetBox's GraphQL API uses the same API authentication tokens as its REST API. Authentication tokens are included with requests by attaching an `Authorization` HTTP header in the following form:

+ 22 - 11
netbox/circuits/graphql/types.py

@@ -32,7 +32,8 @@ __all__ = (
 @strawberry_django.type(
 @strawberry_django.type(
     models.Provider,
     models.Provider,
     fields='__all__',
     fields='__all__',
-    filters=ProviderFilter
+    filters=ProviderFilter,
+    pagination=True
 )
 )
 class ProviderType(NetBoxObjectType, ContactsMixin):
 class ProviderType(NetBoxObjectType, ContactsMixin):
 
 
@@ -45,7 +46,8 @@ class ProviderType(NetBoxObjectType, ContactsMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ProviderAccount,
     models.ProviderAccount,
     fields='__all__',
     fields='__all__',
-    filters=ProviderAccountFilter
+    filters=ProviderAccountFilter,
+    pagination=True
 )
 )
 class ProviderAccountType(NetBoxObjectType):
 class ProviderAccountType(NetBoxObjectType):
     provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')]
     provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')]
@@ -56,7 +58,8 @@ class ProviderAccountType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ProviderNetwork,
     models.ProviderNetwork,
     fields='__all__',
     fields='__all__',
-    filters=ProviderNetworkFilter
+    filters=ProviderNetworkFilter,
+    pagination=True
 )
 )
 class ProviderNetworkType(NetBoxObjectType):
 class ProviderNetworkType(NetBoxObjectType):
     provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')]
     provider: Annotated["ProviderType", strawberry.lazy('circuits.graphql.types')]
@@ -67,7 +70,8 @@ class ProviderNetworkType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CircuitTermination,
     models.CircuitTermination,
     exclude=['termination_type', 'termination_id', '_location', '_region', '_site', '_site_group', '_provider_network'],
     exclude=['termination_type', 'termination_id', '_location', '_region', '_site', '_site_group', '_provider_network'],
-    filters=CircuitTerminationFilter
+    filters=CircuitTerminationFilter,
+    pagination=True
 )
 )
 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')]
@@ -86,7 +90,8 @@ class CircuitTerminationType(CustomFieldsMixin, TagsMixin, CabledObjectMixin, Ob
 @strawberry_django.type(
 @strawberry_django.type(
     models.CircuitType,
     models.CircuitType,
     fields='__all__',
     fields='__all__',
-    filters=CircuitTypeFilter
+    filters=CircuitTypeFilter,
+    pagination=True
 )
 )
 class CircuitTypeType(OrganizationalObjectType):
 class CircuitTypeType(OrganizationalObjectType):
     color: str
     color: str
@@ -97,7 +102,8 @@ class CircuitTypeType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Circuit,
     models.Circuit,
     fields='__all__',
     fields='__all__',
-    filters=CircuitFilter
+    filters=CircuitFilter,
+    pagination=True
 )
 )
 class CircuitType(NetBoxObjectType, ContactsMixin):
 class CircuitType(NetBoxObjectType, ContactsMixin):
     provider: ProviderType
     provider: ProviderType
@@ -113,7 +119,8 @@ class CircuitType(NetBoxObjectType, ContactsMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CircuitGroup,
     models.CircuitGroup,
     fields='__all__',
     fields='__all__',
-    filters=CircuitGroupFilter
+    filters=CircuitGroupFilter,
+    pagination=True
 )
 )
 class CircuitGroupType(OrganizationalObjectType):
 class CircuitGroupType(OrganizationalObjectType):
     tenant: TenantType | None
     tenant: TenantType | None
@@ -122,7 +129,8 @@ class CircuitGroupType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CircuitGroupAssignment,
     models.CircuitGroupAssignment,
     exclude=['member_type', 'member_id'],
     exclude=['member_type', 'member_id'],
-    filters=CircuitGroupAssignmentFilter
+    filters=CircuitGroupAssignmentFilter,
+    pagination=True
 )
 )
 class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
 class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
     group: Annotated["CircuitGroupType", strawberry.lazy('circuits.graphql.types')]
     group: Annotated["CircuitGroupType", strawberry.lazy('circuits.graphql.types')]
@@ -138,7 +146,8 @@ class CircuitGroupAssignmentType(TagsMixin, BaseObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualCircuitType,
     models.VirtualCircuitType,
     fields='__all__',
     fields='__all__',
-    filters=VirtualCircuitTypeFilter
+    filters=VirtualCircuitTypeFilter,
+    pagination=True
 )
 )
 class VirtualCircuitTypeType(OrganizationalObjectType):
 class VirtualCircuitTypeType(OrganizationalObjectType):
     color: str
     color: str
@@ -149,7 +158,8 @@ class VirtualCircuitTypeType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualCircuitTermination,
     models.VirtualCircuitTermination,
     fields='__all__',
     fields='__all__',
-    filters=VirtualCircuitTerminationFilter
+    filters=VirtualCircuitTerminationFilter,
+    pagination=True
 )
 )
 class VirtualCircuitTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
 class VirtualCircuitTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
     virtual_circuit: Annotated[
     virtual_circuit: Annotated[
@@ -165,7 +175,8 @@ class VirtualCircuitTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualCircuit,
     models.VirtualCircuit,
     fields='__all__',
     fields='__all__',
-    filters=VirtualCircuitFilter
+    filters=VirtualCircuitFilter,
+    pagination=True
 )
 )
 class VirtualCircuitType(NetBoxObjectType):
 class VirtualCircuitType(NetBoxObjectType):
     provider_network: ProviderNetworkType = strawberry_django.field(select_related=["provider_network"])
     provider_network: ProviderNetworkType = strawberry_django.field(select_related=["provider_network"])

+ 11 - 4
netbox/core/graphql/types.py

@@ -19,7 +19,8 @@ __all__ = (
 @strawberry_django.type(
 @strawberry_django.type(
     models.DataFile,
     models.DataFile,
     exclude=['data',],
     exclude=['data',],
-    filters=DataFileFilter
+    filters=DataFileFilter,
+    pagination=True
 )
 )
 class DataFileType(BaseObjectType):
 class DataFileType(BaseObjectType):
     source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')]
     source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')]
@@ -28,7 +29,8 @@ class DataFileType(BaseObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.DataSource,
     models.DataSource,
     fields='__all__',
     fields='__all__',
-    filters=DataSourceFilter
+    filters=DataSourceFilter,
+    pagination=True
 )
 )
 class DataSourceType(NetBoxObjectType):
 class DataSourceType(NetBoxObjectType):
 
 
@@ -38,12 +40,17 @@ class DataSourceType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ObjectChange,
     models.ObjectChange,
     fields='__all__',
     fields='__all__',
-    filters=ObjectChangeFilter
+    filters=ObjectChangeFilter,
+    pagination=True
 )
 )
 class ObjectChangeType(BaseObjectType):
 class ObjectChangeType(BaseObjectType):
     pass
     pass
 
 
 
 
-@strawberry_django.type(DjangoContentType, fields='__all__')
+@strawberry_django.type(
+    DjangoContentType,
+    fields='__all__',
+    pagination=True
+)
 class ContentType:
 class ContentType:
     pass
     pass

+ 86 - 43
netbox/dcim/graphql/types.py

@@ -133,7 +133,8 @@ class ModularComponentTemplateType(ComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CableTermination,
     models.CableTermination,
     exclude=['termination_type', 'termination_id', '_device', '_rack', '_location', '_site'],
     exclude=['termination_type', 'termination_id', '_device', '_rack', '_location', '_site'],
-    filters=CableTerminationFilter
+    filters=CableTerminationFilter,
+    pagination=True
 )
 )
 class CableTerminationType(NetBoxObjectType):
 class CableTerminationType(NetBoxObjectType):
     cable: Annotated["CableType", strawberry.lazy('dcim.graphql.types')] | None
     cable: Annotated["CableType", strawberry.lazy('dcim.graphql.types')] | None
@@ -153,7 +154,8 @@ class CableTerminationType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Cable,
     models.Cable,
     fields='__all__',
     fields='__all__',
-    filters=CableFilter
+    filters=CableFilter,
+    pagination=True
 )
 )
 class CableType(NetBoxObjectType):
 class CableType(NetBoxObjectType):
     color: str
     color: str
@@ -189,7 +191,8 @@ class CableType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ConsolePort,
     models.ConsolePort,
     exclude=['_path'],
     exclude=['_path'],
-    filters=ConsolePortFilter
+    filters=ConsolePortFilter,
+    pagination=True
 )
 )
 class ConsolePortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 class ConsolePortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
     pass
     pass
@@ -198,7 +201,8 @@ class ConsolePortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin
 @strawberry_django.type(
 @strawberry_django.type(
     models.ConsolePortTemplate,
     models.ConsolePortTemplate,
     fields='__all__',
     fields='__all__',
-    filters=ConsolePortTemplateFilter
+    filters=ConsolePortTemplateFilter,
+    pagination=True
 )
 )
 class ConsolePortTemplateType(ModularComponentTemplateType):
 class ConsolePortTemplateType(ModularComponentTemplateType):
     pass
     pass
@@ -207,7 +211,8 @@ class ConsolePortTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ConsoleServerPort,
     models.ConsoleServerPort,
     exclude=['_path'],
     exclude=['_path'],
-    filters=ConsoleServerPortFilter
+    filters=ConsoleServerPortFilter,
+    pagination=True
 )
 )
 class ConsoleServerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 class ConsoleServerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
     pass
     pass
@@ -216,7 +221,8 @@ class ConsoleServerPortType(ModularComponentType, CabledObjectMixin, PathEndpoin
 @strawberry_django.type(
 @strawberry_django.type(
     models.ConsoleServerPortTemplate,
     models.ConsoleServerPortTemplate,
     fields='__all__',
     fields='__all__',
-    filters=ConsoleServerPortTemplateFilter
+    filters=ConsoleServerPortTemplateFilter,
+    pagination=True
 )
 )
 class ConsoleServerPortTemplateType(ModularComponentTemplateType):
 class ConsoleServerPortTemplateType(ModularComponentTemplateType):
     pass
     pass
@@ -225,7 +231,8 @@ class ConsoleServerPortTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Device,
     models.Device,
     fields='__all__',
     fields='__all__',
-    filters=DeviceFilter
+    filters=DeviceFilter,
+    pagination=True
 )
 )
 class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObjectType):
 class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObjectType):
     console_port_count: BigInt
     console_port_count: BigInt
@@ -280,7 +287,8 @@ class DeviceType(ConfigContextMixin, ImageAttachmentsMixin, ContactsMixin, NetBo
 @strawberry_django.type(
 @strawberry_django.type(
     models.DeviceBay,
     models.DeviceBay,
     fields='__all__',
     fields='__all__',
-    filters=DeviceBayFilter
+    filters=DeviceBayFilter,
+    pagination=True
 )
 )
 class DeviceBayType(ComponentType):
 class DeviceBayType(ComponentType):
     installed_device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
     installed_device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
@@ -289,7 +297,8 @@ class DeviceBayType(ComponentType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.DeviceBayTemplate,
     models.DeviceBayTemplate,
     fields='__all__',
     fields='__all__',
-    filters=DeviceBayTemplateFilter
+    filters=DeviceBayTemplateFilter,
+    pagination=True
 )
 )
 class DeviceBayTemplateType(ComponentTemplateType):
 class DeviceBayTemplateType(ComponentTemplateType):
     pass
     pass
@@ -298,7 +307,8 @@ class DeviceBayTemplateType(ComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.InventoryItemTemplate,
     models.InventoryItemTemplate,
     exclude=['component_type', 'component_id', 'parent'],
     exclude=['component_type', 'component_id', 'parent'],
-    filters=InventoryItemTemplateFilter
+    filters=InventoryItemTemplateFilter,
+    pagination=True
 )
 )
 class InventoryItemTemplateType(ComponentTemplateType):
 class InventoryItemTemplateType(ComponentTemplateType):
     role: Annotated["InventoryItemRoleType", strawberry.lazy('dcim.graphql.types')] | None
     role: Annotated["InventoryItemRoleType", strawberry.lazy('dcim.graphql.types')] | None
@@ -324,7 +334,8 @@ class InventoryItemTemplateType(ComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.DeviceRole,
     models.DeviceRole,
     fields='__all__',
     fields='__all__',
-    filters=DeviceRoleFilter
+    filters=DeviceRoleFilter,
+    pagination=True
 )
 )
 class DeviceRoleType(OrganizationalObjectType):
 class DeviceRoleType(OrganizationalObjectType):
     color: str
     color: str
@@ -337,7 +348,8 @@ class DeviceRoleType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.DeviceType,
     models.DeviceType,
     fields='__all__',
     fields='__all__',
-    filters=DeviceTypeFilter
+    filters=DeviceTypeFilter,
+    pagination=True
 )
 )
 class DeviceTypeType(NetBoxObjectType):
 class DeviceTypeType(NetBoxObjectType):
     console_port_template_count: BigInt
     console_port_template_count: BigInt
@@ -371,7 +383,8 @@ class DeviceTypeType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.FrontPort,
     models.FrontPort,
     fields='__all__',
     fields='__all__',
-    filters=FrontPortFilter
+    filters=FrontPortFilter,
+    pagination=True
 )
 )
 class FrontPortType(ModularComponentType, CabledObjectMixin):
 class FrontPortType(ModularComponentType, CabledObjectMixin):
     color: str
     color: str
@@ -381,7 +394,8 @@ class FrontPortType(ModularComponentType, CabledObjectMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.FrontPortTemplate,
     models.FrontPortTemplate,
     fields='__all__',
     fields='__all__',
-    filters=FrontPortTemplateFilter
+    filters=FrontPortTemplateFilter,
+    pagination=True
 )
 )
 class FrontPortTemplateType(ModularComponentTemplateType):
 class FrontPortTemplateType(ModularComponentTemplateType):
     color: str
     color: str
@@ -391,7 +405,8 @@ class FrontPortTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.MACAddress,
     models.MACAddress,
     exclude=['assigned_object_type', 'assigned_object_id'],
     exclude=['assigned_object_type', 'assigned_object_id'],
-    filters=MACAddressFilter
+    filters=MACAddressFilter,
+    pagination=True
 )
 )
 class MACAddressType(NetBoxObjectType):
 class MACAddressType(NetBoxObjectType):
     mac_address: str
     mac_address: str
@@ -407,7 +422,8 @@ class MACAddressType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Interface,
     models.Interface,
     exclude=['_path'],
     exclude=['_path'],
-    filters=InterfaceFilter
+    filters=InterfaceFilter,
+    pagination=True
 )
 )
 class InterfaceType(IPAddressesMixin, ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 class InterfaceType(IPAddressesMixin, ModularComponentType, CabledObjectMixin, PathEndpointMixin):
     _name: str
     _name: str
@@ -434,7 +450,8 @@ class InterfaceType(IPAddressesMixin, ModularComponentType, CabledObjectMixin, P
 @strawberry_django.type(
 @strawberry_django.type(
     models.InterfaceTemplate,
     models.InterfaceTemplate,
     fields='__all__',
     fields='__all__',
-    filters=InterfaceTemplateFilter
+    filters=InterfaceTemplateFilter,
+    pagination=True
 )
 )
 class InterfaceTemplateType(ModularComponentTemplateType):
 class InterfaceTemplateType(ModularComponentTemplateType):
     _name: str
     _name: str
@@ -446,7 +463,8 @@ class InterfaceTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.InventoryItem,
     models.InventoryItem,
     exclude=['component_type', 'component_id', 'parent'],
     exclude=['component_type', 'component_id', 'parent'],
-    filters=InventoryItemFilter
+    filters=InventoryItemFilter,
+    pagination=True
 )
 )
 class InventoryItemType(ComponentType):
 class InventoryItemType(ComponentType):
     role: Annotated["InventoryItemRoleType", strawberry.lazy('dcim.graphql.types')] | None
     role: Annotated["InventoryItemRoleType", strawberry.lazy('dcim.graphql.types')] | None
@@ -472,7 +490,8 @@ class InventoryItemType(ComponentType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.InventoryItemRole,
     models.InventoryItemRole,
     fields='__all__',
     fields='__all__',
-    filters=InventoryItemRoleFilter
+    filters=InventoryItemRoleFilter,
+    pagination=True
 )
 )
 class InventoryItemRoleType(OrganizationalObjectType):
 class InventoryItemRoleType(OrganizationalObjectType):
     color: str
     color: str
@@ -485,7 +504,8 @@ class InventoryItemRoleType(OrganizationalObjectType):
     models.Location,
     models.Location,
     # fields='__all__',
     # fields='__all__',
     exclude=['parent'],  # bug - temp
     exclude=['parent'],  # bug - temp
-    filters=LocationFilter
+    filters=LocationFilter,
+    pagination=True
 )
 )
 class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, OrganizationalObjectType):
 class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, OrganizationalObjectType):
     site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
     site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
@@ -512,7 +532,8 @@ class LocationType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, Organi
 @strawberry_django.type(
 @strawberry_django.type(
     models.Manufacturer,
     models.Manufacturer,
     fields='__all__',
     fields='__all__',
-    filters=ManufacturerFilter
+    filters=ManufacturerFilter,
+    pagination=True
 )
 )
 class ManufacturerType(OrganizationalObjectType, ContactsMixin):
 class ManufacturerType(OrganizationalObjectType, ContactsMixin):
 
 
@@ -526,7 +547,8 @@ class ManufacturerType(OrganizationalObjectType, ContactsMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Module,
     models.Module,
     fields='__all__',
     fields='__all__',
-    filters=ModuleFilter
+    filters=ModuleFilter,
+    pagination=True
 )
 )
 class ModuleType(NetBoxObjectType):
 class ModuleType(NetBoxObjectType):
     device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]
     device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')]
@@ -546,7 +568,8 @@ class ModuleType(NetBoxObjectType):
     models.ModuleBay,
     models.ModuleBay,
     # fields='__all__',
     # fields='__all__',
     exclude=['parent'],
     exclude=['parent'],
-    filters=ModuleBayFilter
+    filters=ModuleBayFilter,
+    pagination=True
 )
 )
 class ModuleBayType(ModularComponentType):
 class ModuleBayType(ModularComponentType):
 
 
@@ -561,7 +584,8 @@ class ModuleBayType(ModularComponentType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ModuleBayTemplate,
     models.ModuleBayTemplate,
     fields='__all__',
     fields='__all__',
-    filters=ModuleBayTemplateFilter
+    filters=ModuleBayTemplateFilter,
+    pagination=True
 )
 )
 class ModuleBayTemplateType(ModularComponentTemplateType):
 class ModuleBayTemplateType(ModularComponentTemplateType):
     pass
     pass
@@ -570,7 +594,8 @@ class ModuleBayTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ModuleType,
     models.ModuleType,
     fields='__all__',
     fields='__all__',
-    filters=ModuleTypeFilter
+    filters=ModuleTypeFilter,
+    pagination=True
 )
 )
 class ModuleTypeType(NetBoxObjectType):
 class ModuleTypeType(NetBoxObjectType):
     manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
     manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
@@ -588,7 +613,8 @@ class ModuleTypeType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Platform,
     models.Platform,
     fields='__all__',
     fields='__all__',
-    filters=PlatformFilter
+    filters=PlatformFilter,
+    pagination=True
 )
 )
 class PlatformType(OrganizationalObjectType):
 class PlatformType(OrganizationalObjectType):
     manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] | None
     manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')] | None
@@ -601,7 +627,8 @@ class PlatformType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.PowerFeed,
     models.PowerFeed,
     exclude=['_path'],
     exclude=['_path'],
-    filters=PowerFeedFilter
+    filters=PowerFeedFilter,
+    pagination=True
 )
 )
 class PowerFeedType(NetBoxObjectType, CabledObjectMixin, PathEndpointMixin):
 class PowerFeedType(NetBoxObjectType, CabledObjectMixin, PathEndpointMixin):
     power_panel: Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]
     power_panel: Annotated["PowerPanelType", strawberry.lazy('dcim.graphql.types')]
@@ -612,7 +639,8 @@ class PowerFeedType(NetBoxObjectType, CabledObjectMixin, PathEndpointMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.PowerOutlet,
     models.PowerOutlet,
     exclude=['_path'],
     exclude=['_path'],
-    filters=PowerOutletFilter
+    filters=PowerOutletFilter,
+    pagination=True
 )
 )
 class PowerOutletType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 class PowerOutletType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
     power_port: Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')] | None
     power_port: Annotated["PowerPortType", strawberry.lazy('dcim.graphql.types')] | None
@@ -622,7 +650,8 @@ class PowerOutletType(ModularComponentType, CabledObjectMixin, PathEndpointMixin
 @strawberry_django.type(
 @strawberry_django.type(
     models.PowerOutletTemplate,
     models.PowerOutletTemplate,
     fields='__all__',
     fields='__all__',
-    filters=PowerOutletTemplateFilter
+    filters=PowerOutletTemplateFilter,
+    pagination=True
 )
 )
 class PowerOutletTemplateType(ModularComponentTemplateType):
 class PowerOutletTemplateType(ModularComponentTemplateType):
     power_port: Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')] | None
     power_port: Annotated["PowerPortTemplateType", strawberry.lazy('dcim.graphql.types')] | None
@@ -631,7 +660,8 @@ class PowerOutletTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.PowerPanel,
     models.PowerPanel,
     fields='__all__',
     fields='__all__',
-    filters=PowerPanelFilter
+    filters=PowerPanelFilter,
+    pagination=True
 )
 )
 class PowerPanelType(NetBoxObjectType, ContactsMixin):
 class PowerPanelType(NetBoxObjectType, ContactsMixin):
     site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
     site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
@@ -643,7 +673,8 @@ class PowerPanelType(NetBoxObjectType, ContactsMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.PowerPort,
     models.PowerPort,
     exclude=['_path'],
     exclude=['_path'],
-    filters=PowerPortFilter
+    filters=PowerPortFilter,
+    pagination=True
 )
 )
 class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 
 
@@ -653,7 +684,8 @@ class PowerPortType(ModularComponentType, CabledObjectMixin, PathEndpointMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.PowerPortTemplate,
     models.PowerPortTemplate,
     fields='__all__',
     fields='__all__',
-    filters=PowerPortTemplateFilter
+    filters=PowerPortTemplateFilter,
+    pagination=True
 )
 )
 class PowerPortTemplateType(ModularComponentTemplateType):
 class PowerPortTemplateType(ModularComponentTemplateType):
     poweroutlet_templates: List[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]]
     poweroutlet_templates: List[Annotated["PowerOutletTemplateType", strawberry.lazy('dcim.graphql.types')]]
@@ -662,7 +694,8 @@ class PowerPortTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.RackType,
     models.RackType,
     fields='__all__',
     fields='__all__',
-    filters=RackTypeFilter
+    filters=RackTypeFilter,
+    pagination=True
 )
 )
 class RackTypeType(NetBoxObjectType):
 class RackTypeType(NetBoxObjectType):
     manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
     manufacturer: Annotated["ManufacturerType", strawberry.lazy('dcim.graphql.types')]
@@ -671,7 +704,8 @@ class RackTypeType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Rack,
     models.Rack,
     fields='__all__',
     fields='__all__',
-    filters=RackFilter
+    filters=RackFilter,
+    pagination=True
 )
 )
 class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObjectType):
 class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObjectType):
     site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
     site: Annotated["SiteType", strawberry.lazy('dcim.graphql.types')]
@@ -689,7 +723,8 @@ class RackType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObje
 @strawberry_django.type(
 @strawberry_django.type(
     models.RackReservation,
     models.RackReservation,
     fields='__all__',
     fields='__all__',
-    filters=RackReservationFilter
+    filters=RackReservationFilter,
+    pagination=True
 )
 )
 class RackReservationType(NetBoxObjectType):
 class RackReservationType(NetBoxObjectType):
     units: List[int]
     units: List[int]
@@ -701,7 +736,8 @@ class RackReservationType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.RackRole,
     models.RackRole,
     fields='__all__',
     fields='__all__',
-    filters=RackRoleFilter
+    filters=RackRoleFilter,
+    pagination=True
 )
 )
 class RackRoleType(OrganizationalObjectType):
 class RackRoleType(OrganizationalObjectType):
     color: str
     color: str
@@ -712,7 +748,8 @@ class RackRoleType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.RearPort,
     models.RearPort,
     fields='__all__',
     fields='__all__',
-    filters=RearPortFilter
+    filters=RearPortFilter,
+    pagination=True
 )
 )
 class RearPortType(ModularComponentType, CabledObjectMixin):
 class RearPortType(ModularComponentType, CabledObjectMixin):
     color: str
     color: str
@@ -723,7 +760,8 @@ class RearPortType(ModularComponentType, CabledObjectMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.RearPortTemplate,
     models.RearPortTemplate,
     fields='__all__',
     fields='__all__',
-    filters=RearPortTemplateFilter
+    filters=RearPortTemplateFilter,
+    pagination=True
 )
 )
 class RearPortTemplateType(ModularComponentTemplateType):
 class RearPortTemplateType(ModularComponentTemplateType):
     color: str
     color: str
@@ -734,7 +772,8 @@ class RearPortTemplateType(ModularComponentTemplateType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Region,
     models.Region,
     exclude=['parent'],
     exclude=['parent'],
-    filters=RegionFilter
+    filters=RegionFilter,
+    pagination=True
 )
 )
 class RegionType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
 class RegionType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
 
 
@@ -759,7 +798,8 @@ class RegionType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Site,
     models.Site,
     fields='__all__',
     fields='__all__',
-    filters=SiteFilter
+    filters=SiteFilter,
+    pagination=True
 )
 )
 class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObjectType):
 class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObjectType):
     time_zone: str | None
     time_zone: str | None
@@ -793,7 +833,8 @@ class SiteType(VLANGroupsMixin, ImageAttachmentsMixin, ContactsMixin, NetBoxObje
 @strawberry_django.type(
 @strawberry_django.type(
     models.SiteGroup,
     models.SiteGroup,
     exclude=['parent'],  # bug - temp
     exclude=['parent'],  # bug - temp
-    filters=SiteGroupFilter
+    filters=SiteGroupFilter,
+    pagination=True
 )
 )
 class SiteGroupType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
 class SiteGroupType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
 
 
@@ -818,7 +859,8 @@ class SiteGroupType(VLANGroupsMixin, ContactsMixin, OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualChassis,
     models.VirtualChassis,
     fields='__all__',
     fields='__all__',
-    filters=VirtualChassisFilter
+    filters=VirtualChassisFilter,
+    pagination=True
 )
 )
 class VirtualChassisType(NetBoxObjectType):
 class VirtualChassisType(NetBoxObjectType):
     member_count: BigInt
     member_count: BigInt
@@ -830,7 +872,8 @@ class VirtualChassisType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualDeviceContext,
     models.VirtualDeviceContext,
     fields='__all__',
     fields='__all__',
-    filters=VirtualDeviceContextFilter
+    filters=VirtualDeviceContextFilter,
+    pagination=True
 )
 )
 class VirtualDeviceContextType(NetBoxObjectType):
 class VirtualDeviceContextType(NetBoxObjectType):
     device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None
     device: Annotated["DeviceType", strawberry.lazy('dcim.graphql.types')] | None

+ 28 - 13
netbox/extras/graphql/types.py

@@ -46,7 +46,8 @@ __all__ = (
 @strawberry_django.type(
 @strawberry_django.type(
     models.ConfigContext,
     models.ConfigContext,
     fields='__all__',
     fields='__all__',
-    filters=ConfigContextFilter
+    filters=ConfigContextFilter,
+    pagination=True
 )
 )
 class ConfigContextType(ObjectType):
 class ConfigContextType(ObjectType):
     data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
     data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
@@ -69,7 +70,8 @@ class ConfigContextType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ConfigTemplate,
     models.ConfigTemplate,
     fields='__all__',
     fields='__all__',
-    filters=ConfigTemplateFilter
+    filters=ConfigTemplateFilter,
+    pagination=True
 )
 )
 class ConfigTemplateType(TagsMixin, ObjectType):
 class ConfigTemplateType(TagsMixin, ObjectType):
     data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
     data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
@@ -84,7 +86,8 @@ class ConfigTemplateType(TagsMixin, ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CustomField,
     models.CustomField,
     fields='__all__',
     fields='__all__',
-    filters=CustomFieldFilter
+    filters=CustomFieldFilter,
+    pagination=True
 )
 )
 class CustomFieldType(ObjectType):
 class CustomFieldType(ObjectType):
     related_object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
     related_object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
@@ -94,7 +97,8 @@ class CustomFieldType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CustomFieldChoiceSet,
     models.CustomFieldChoiceSet,
     exclude=['extra_choices'],
     exclude=['extra_choices'],
-    filters=CustomFieldChoiceSetFilter
+    filters=CustomFieldChoiceSetFilter,
+    pagination=True
 )
 )
 class CustomFieldChoiceSetType(ObjectType):
 class CustomFieldChoiceSetType(ObjectType):
 
 
@@ -105,7 +109,8 @@ class CustomFieldChoiceSetType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.CustomLink,
     models.CustomLink,
     fields='__all__',
     fields='__all__',
-    filters=CustomLinkFilter
+    filters=CustomLinkFilter,
+    pagination=True
 )
 )
 class CustomLinkType(ObjectType):
 class CustomLinkType(ObjectType):
     pass
     pass
@@ -114,7 +119,8 @@ class CustomLinkType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ExportTemplate,
     models.ExportTemplate,
     fields='__all__',
     fields='__all__',
-    filters=ExportTemplateFilter
+    filters=ExportTemplateFilter,
+    pagination=True
 )
 )
 class ExportTemplateType(ObjectType):
 class ExportTemplateType(ObjectType):
     data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
     data_source: Annotated["DataSourceType", strawberry.lazy('core.graphql.types')] | None
@@ -124,7 +130,8 @@ class ExportTemplateType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ImageAttachment,
     models.ImageAttachment,
     fields='__all__',
     fields='__all__',
-    filters=ImageAttachmentFilter
+    filters=ImageAttachmentFilter,
+    pagination=True
 )
 )
 class ImageAttachmentType(BaseObjectType):
 class ImageAttachmentType(BaseObjectType):
     object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
     object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
@@ -133,7 +140,8 @@ class ImageAttachmentType(BaseObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.JournalEntry,
     models.JournalEntry,
     fields='__all__',
     fields='__all__',
-    filters=JournalEntryFilter
+    filters=JournalEntryFilter,
+    pagination=True
 )
 )
 class JournalEntryType(CustomFieldsMixin, TagsMixin, ObjectType):
 class JournalEntryType(CustomFieldsMixin, TagsMixin, ObjectType):
     assigned_object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
     assigned_object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
@@ -143,6 +151,7 @@ class JournalEntryType(CustomFieldsMixin, TagsMixin, ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Notification,
     models.Notification,
     # filters=NotificationFilter
     # filters=NotificationFilter
+    pagination=True
 )
 )
 class NotificationType(ObjectType):
 class NotificationType(ObjectType):
     user: Annotated["UserType", strawberry.lazy('users.graphql.types')] | None
     user: Annotated["UserType", strawberry.lazy('users.graphql.types')] | None
@@ -150,7 +159,8 @@ class NotificationType(ObjectType):
 
 
 @strawberry_django.type(
 @strawberry_django.type(
     models.NotificationGroup,
     models.NotificationGroup,
-    filters=NotificationGroupFilter
+    filters=NotificationGroupFilter,
+    pagination=True
 )
 )
 class NotificationGroupType(ObjectType):
 class NotificationGroupType(ObjectType):
     users: List[Annotated["UserType", strawberry.lazy('users.graphql.types')]]
     users: List[Annotated["UserType", strawberry.lazy('users.graphql.types')]]
@@ -160,7 +170,8 @@ class NotificationGroupType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.SavedFilter,
     models.SavedFilter,
     exclude=['content_types',],
     exclude=['content_types',],
-    filters=SavedFilterFilter
+    filters=SavedFilterFilter,
+    pagination=True
 )
 )
 class SavedFilterType(ObjectType):
 class SavedFilterType(ObjectType):
     user: Annotated["UserType", strawberry.lazy('users.graphql.types')] | None
     user: Annotated["UserType", strawberry.lazy('users.graphql.types')] | None
@@ -169,6 +180,7 @@ class SavedFilterType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Subscription,
     models.Subscription,
     # filters=NotificationFilter
     # filters=NotificationFilter
+    pagination=True
 )
 )
 class SubscriptionType(ObjectType):
 class SubscriptionType(ObjectType):
     user: Annotated["UserType", strawberry.lazy('users.graphql.types')] | None
     user: Annotated["UserType", strawberry.lazy('users.graphql.types')] | None
@@ -177,7 +189,8 @@ class SubscriptionType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Tag,
     models.Tag,
     exclude=['extras_taggeditem_items', ],
     exclude=['extras_taggeditem_items', ],
-    filters=TagFilter
+    filters=TagFilter,
+    pagination=True
 )
 )
 class TagType(ObjectType):
 class TagType(ObjectType):
     color: str
     color: str
@@ -188,7 +201,8 @@ class TagType(ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Webhook,
     models.Webhook,
     exclude=['content_types',],
     exclude=['content_types',],
-    filters=WebhookFilter
+    filters=WebhookFilter,
+    pagination=True
 )
 )
 class WebhookType(OrganizationalObjectType):
 class WebhookType(OrganizationalObjectType):
     pass
     pass
@@ -197,7 +211,8 @@ class WebhookType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.EventRule,
     models.EventRule,
     exclude=['content_types',],
     exclude=['content_types',],
-    filters=EventRuleFilter
+    filters=EventRuleFilter,
+    pagination=True
 )
 )
 class EventRuleType(OrganizationalObjectType):
 class EventRuleType(OrganizationalObjectType):
     action_object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None
     action_object_type: Annotated["ContentTypeType", strawberry.lazy('netbox.graphql.types')] | None

+ 36 - 18
netbox/ipam/graphql/types.py

@@ -70,7 +70,8 @@ class BaseIPAddressFamilyType:
 @strawberry_django.type(
 @strawberry_django.type(
     models.ASN,
     models.ASN,
     fields='__all__',
     fields='__all__',
-    filters=ASNFilter
+    filters=ASNFilter,
+    pagination=True
 )
 )
 class ASNType(NetBoxObjectType):
 class ASNType(NetBoxObjectType):
     asn: BigInt
     asn: BigInt
@@ -84,7 +85,8 @@ class ASNType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ASNRange,
     models.ASNRange,
     fields='__all__',
     fields='__all__',
-    filters=ASNRangeFilter
+    filters=ASNRangeFilter,
+    pagination=True
 )
 )
 class ASNRangeType(NetBoxObjectType):
 class ASNRangeType(NetBoxObjectType):
     start: BigInt
     start: BigInt
@@ -96,7 +98,8 @@ class ASNRangeType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Aggregate,
     models.Aggregate,
     fields='__all__',
     fields='__all__',
-    filters=AggregateFilter
+    filters=AggregateFilter,
+    pagination=True
 )
 )
 class AggregateType(NetBoxObjectType, BaseIPAddressFamilyType):
 class AggregateType(NetBoxObjectType, BaseIPAddressFamilyType):
     prefix: str
     prefix: str
@@ -107,7 +110,8 @@ class AggregateType(NetBoxObjectType, BaseIPAddressFamilyType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.FHRPGroup,
     models.FHRPGroup,
     fields='__all__',
     fields='__all__',
-    filters=FHRPGroupFilter
+    filters=FHRPGroupFilter,
+    pagination=True
 )
 )
 class FHRPGroupType(NetBoxObjectType, IPAddressesMixin):
 class FHRPGroupType(NetBoxObjectType, IPAddressesMixin):
 
 
@@ -117,7 +121,8 @@ class FHRPGroupType(NetBoxObjectType, IPAddressesMixin):
 @strawberry_django.type(
 @strawberry_django.type(
     models.FHRPGroupAssignment,
     models.FHRPGroupAssignment,
     exclude=['interface_type', 'interface_id'],
     exclude=['interface_type', 'interface_id'],
-    filters=FHRPGroupAssignmentFilter
+    filters=FHRPGroupAssignmentFilter,
+    pagination=True
 )
 )
 class FHRPGroupAssignmentType(BaseObjectType):
 class FHRPGroupAssignmentType(BaseObjectType):
     group: Annotated["FHRPGroupType", strawberry.lazy('ipam.graphql.types')]
     group: Annotated["FHRPGroupType", strawberry.lazy('ipam.graphql.types')]
@@ -133,7 +138,8 @@ class FHRPGroupAssignmentType(BaseObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IPAddress,
     models.IPAddress,
     exclude=['assigned_object_type', 'assigned_object_id', 'address'],
     exclude=['assigned_object_type', 'assigned_object_id', 'address'],
-    filters=IPAddressFilter
+    filters=IPAddressFilter,
+    pagination=True
 )
 )
 class IPAddressType(NetBoxObjectType, BaseIPAddressFamilyType):
 class IPAddressType(NetBoxObjectType, BaseIPAddressFamilyType):
     address: str
     address: str
@@ -157,7 +163,8 @@ class IPAddressType(NetBoxObjectType, BaseIPAddressFamilyType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IPRange,
     models.IPRange,
     fields='__all__',
     fields='__all__',
-    filters=IPRangeFilter
+    filters=IPRangeFilter,
+    pagination=True
 )
 )
 class IPRangeType(NetBoxObjectType):
 class IPRangeType(NetBoxObjectType):
     start_address: str
     start_address: str
@@ -170,7 +177,8 @@ class IPRangeType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Prefix,
     models.Prefix,
     exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
     exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
-    filters=PrefixFilter
+    filters=PrefixFilter,
+    pagination=True
 )
 )
 class PrefixType(NetBoxObjectType, BaseIPAddressFamilyType):
 class PrefixType(NetBoxObjectType, BaseIPAddressFamilyType):
     prefix: str
     prefix: str
@@ -192,7 +200,8 @@ class PrefixType(NetBoxObjectType, BaseIPAddressFamilyType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.RIR,
     models.RIR,
     fields='__all__',
     fields='__all__',
-    filters=RIRFilter
+    filters=RIRFilter,
+    pagination=True
 )
 )
 class RIRType(OrganizationalObjectType):
 class RIRType(OrganizationalObjectType):
 
 
@@ -204,7 +213,8 @@ class RIRType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Role,
     models.Role,
     fields='__all__',
     fields='__all__',
-    filters=RoleFilter
+    filters=RoleFilter,
+    pagination=True
 )
 )
 class RoleType(OrganizationalObjectType):
 class RoleType(OrganizationalObjectType):
 
 
@@ -216,7 +226,8 @@ class RoleType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.RouteTarget,
     models.RouteTarget,
     fields='__all__',
     fields='__all__',
-    filters=RouteTargetFilter
+    filters=RouteTargetFilter,
+    pagination=True
 )
 )
 class RouteTargetType(NetBoxObjectType):
 class RouteTargetType(NetBoxObjectType):
     tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
     tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
@@ -230,7 +241,8 @@ class RouteTargetType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Service,
     models.Service,
     fields='__all__',
     fields='__all__',
-    filters=ServiceFilter
+    filters=ServiceFilter,
+    pagination=True
 )
 )
 class ServiceType(NetBoxObjectType):
 class ServiceType(NetBoxObjectType):
     ports: List[int]
     ports: List[int]
@@ -243,7 +255,8 @@ class ServiceType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ServiceTemplate,
     models.ServiceTemplate,
     fields='__all__',
     fields='__all__',
-    filters=ServiceTemplateFilter
+    filters=ServiceTemplateFilter,
+    pagination=True
 )
 )
 class ServiceTemplateType(NetBoxObjectType):
 class ServiceTemplateType(NetBoxObjectType):
     ports: List[int]
     ports: List[int]
@@ -252,7 +265,8 @@ class ServiceTemplateType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VLAN,
     models.VLAN,
     exclude=['qinq_svlan'],
     exclude=['qinq_svlan'],
-    filters=VLANFilter
+    filters=VLANFilter,
+    pagination=True
 )
 )
 class VLANType(NetBoxObjectType):
 class VLANType(NetBoxObjectType):
     site: Annotated["SiteType", strawberry.lazy('ipam.graphql.types')] | None
     site: Annotated["SiteType", strawberry.lazy('ipam.graphql.types')] | None
@@ -275,7 +289,8 @@ class VLANType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VLANGroup,
     models.VLANGroup,
     exclude=['scope_type', 'scope_id'],
     exclude=['scope_type', 'scope_id'],
-    filters=VLANGroupFilter
+    filters=VLANGroupFilter,
+    pagination=True
 )
 )
 class VLANGroupType(OrganizationalObjectType):
 class VLANGroupType(OrganizationalObjectType):
 
 
@@ -299,7 +314,8 @@ class VLANGroupType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VLANTranslationPolicy,
     models.VLANTranslationPolicy,
     fields='__all__',
     fields='__all__',
-    filters=VLANTranslationPolicyFilter
+    filters=VLANTranslationPolicyFilter,
+    pagination=True
 )
 )
 class VLANTranslationPolicyType(NetBoxObjectType):
 class VLANTranslationPolicyType(NetBoxObjectType):
     rules: List[Annotated["VLANTranslationRuleType", strawberry.lazy('ipam.graphql.types')]]
     rules: List[Annotated["VLANTranslationRuleType", strawberry.lazy('ipam.graphql.types')]]
@@ -308,7 +324,8 @@ class VLANTranslationPolicyType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VLANTranslationRule,
     models.VLANTranslationRule,
     fields='__all__',
     fields='__all__',
-    filters=VLANTranslationRuleFilter
+    filters=VLANTranslationRuleFilter,
+    pagination=True
 )
 )
 class VLANTranslationRuleType(NetBoxObjectType):
 class VLANTranslationRuleType(NetBoxObjectType):
     policy: Annotated[
     policy: Annotated[
@@ -320,7 +337,8 @@ class VLANTranslationRuleType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VRF,
     models.VRF,
     fields='__all__',
     fields='__all__',
-    filters=VRFFilter
+    filters=VRFFilter,
+    pagination=True
 )
 )
 class VRFType(NetBoxObjectType):
 class VRFType(NetBoxObjectType):
     tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
     tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None

+ 1 - 1
netbox/netbox/graphql/schema.py

@@ -1,7 +1,7 @@
 import strawberry
 import strawberry
 from django.conf import settings
 from django.conf import settings
 from strawberry_django.optimizer import DjangoOptimizerExtension
 from strawberry_django.optimizer import DjangoOptimizerExtension
-from strawberry.extensions import MaxAliasesLimiter
+from strawberry.extensions import MaxAliasesLimiter  # , SchemaExtension
 from strawberry.schema.config import StrawberryConfig
 from strawberry.schema.config import StrawberryConfig
 
 
 from circuits.graphql.schema import CircuitsQuery
 from circuits.graphql.schema import CircuitsQuery

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

@@ -84,6 +84,7 @@ class NetBoxObjectType(
 @strawberry_django.type(
 @strawberry_django.type(
     ContentType,
     ContentType,
     fields=['id', 'app_label', 'model'],
     fields=['id', 'app_label', 'model'],
+    pagination=True
 )
 )
 class ContentTypeType:
 class ContentTypeType:
     pass
     pass
@@ -92,6 +93,7 @@ class ContentTypeType:
 @strawberry_django.type(
 @strawberry_django.type(
     ObjectType_,
     ObjectType_,
     fields=['id', 'app_label', 'model'],
     fields=['id', 'app_label', 'model'],
+    pagination=True
 )
 )
 class ObjectTypeType:
 class ObjectTypeType:
     pass
     pass

+ 1 - 0
netbox/netbox/settings.py

@@ -798,6 +798,7 @@ LOCALE_PATHS = (
 STRAWBERRY_DJANGO = {
 STRAWBERRY_DJANGO = {
     "DEFAULT_PK_FIELD_NAME": "id",
     "DEFAULT_PK_FIELD_NAME": "id",
     "TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True,
     "TYPE_DESCRIPTION_FROM_MODEL_DOCSTRING": True,
+    "PAGINATION_DEFAULT_LIMIT": 100,
 }
 }
 
 
 #
 #

+ 36 - 6
netbox/tenancy/graphql/types.py

@@ -52,7 +52,12 @@ __all__ = (
 #
 #
 
 
 
 
-@strawberry_django.type(models.Tenant, fields='__all__', filters=TenantFilter)
+@strawberry_django.type(
+    models.Tenant,
+    fields='__all__',
+    filters=TenantFilter,
+    pagination=True
+)
 class TenantType(NetBoxObjectType):
 class TenantType(NetBoxObjectType):
     group: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
     group: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
     contacts: List[Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')]]
     contacts: List[Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')]]
@@ -82,7 +87,12 @@ class TenantType(NetBoxObjectType):
     l2vpns: List[Annotated['L2VPNType', strawberry.lazy('vpn.graphql.types')]]
     l2vpns: List[Annotated['L2VPNType', strawberry.lazy('vpn.graphql.types')]]
 
 
 
 
-@strawberry_django.type(models.TenantGroup, fields='__all__', filters=TenantGroupFilter)
+@strawberry_django.type(
+    models.TenantGroup,
+    fields='__all__',
+    filters=TenantGroupFilter,
+    pagination=True
+)
 class TenantGroupType(OrganizationalObjectType):
 class TenantGroupType(OrganizationalObjectType):
     parent: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
     parent: Annotated['TenantGroupType', strawberry.lazy('tenancy.graphql.types')] | None
 
 
@@ -95,17 +105,32 @@ class TenantGroupType(OrganizationalObjectType):
 #
 #
 
 
 
 
-@strawberry_django.type(models.Contact, fields='__all__', filters=ContactFilter)
+@strawberry_django.type(
+    models.Contact,
+    fields='__all__',
+    filters=ContactFilter,
+    pagination=True
+)
 class ContactType(ContactAssignmentsMixin, NetBoxObjectType):
 class ContactType(ContactAssignmentsMixin, NetBoxObjectType):
     groups: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]]
     groups: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]]
 
 
 
 
-@strawberry_django.type(models.ContactRole, fields='__all__', filters=ContactRoleFilter)
+@strawberry_django.type(
+    models.ContactRole,
+    fields='__all__',
+    filters=ContactRoleFilter,
+    pagination=True
+)
 class ContactRoleType(ContactAssignmentsMixin, OrganizationalObjectType):
 class ContactRoleType(ContactAssignmentsMixin, OrganizationalObjectType):
     pass
     pass
 
 
 
 
-@strawberry_django.type(models.ContactGroup, fields='__all__', filters=ContactGroupFilter)
+@strawberry_django.type(
+    models.ContactGroup,
+    fields='__all__',
+    filters=ContactGroupFilter,
+    pagination=True
+)
 class ContactGroupType(OrganizationalObjectType):
 class ContactGroupType(OrganizationalObjectType):
     parent: Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')] | None
     parent: Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')] | None
 
 
@@ -113,7 +138,12 @@ class ContactGroupType(OrganizationalObjectType):
     children: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]]
     children: List[Annotated['ContactGroupType', strawberry.lazy('tenancy.graphql.types')]]
 
 
 
 
-@strawberry_django.type(models.ContactAssignment, fields='__all__', filters=ContactAssignmentFilter)
+@strawberry_django.type(
+    models.ContactAssignment,
+    fields='__all__',
+    filters=ContactAssignmentFilter,
+    pagination=True
+)
 class ContactAssignmentType(CustomFieldsMixin, TagsMixin, BaseObjectType):
 class ContactAssignmentType(CustomFieldsMixin, TagsMixin, BaseObjectType):
     object_type: Annotated['ContentTypeType', strawberry.lazy('netbox.graphql.types')] | None
     object_type: Annotated['ContentTypeType', strawberry.lazy('netbox.graphql.types')] | None
     contact: Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')] | None
     contact: Annotated['ContactType', strawberry.lazy('tenancy.graphql.types')] | None

+ 4 - 2
netbox/users/graphql/types.py

@@ -15,7 +15,8 @@ __all__ = (
 @strawberry_django.type(
 @strawberry_django.type(
     Group,
     Group,
     fields=['id', 'name'],
     fields=['id', 'name'],
-    filters=GroupFilter
+    filters=GroupFilter,
+    pagination=True
 )
 )
 class GroupType(BaseObjectType):
 class GroupType(BaseObjectType):
     pass
     pass
@@ -26,7 +27,8 @@ class GroupType(BaseObjectType):
     fields=[
     fields=[
         'id', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'groups',
         'id', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'groups',
     ],
     ],
-    filters=UserFilter
+    filters=UserFilter,
+    pagination=True
 )
 )
 class UserType(BaseObjectType):
 class UserType(BaseObjectType):
     groups: List[GroupType]
     groups: List[GroupType]

+ 12 - 6
netbox/virtualization/graphql/types.py

@@ -46,7 +46,8 @@ class ComponentType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Cluster,
     models.Cluster,
     exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
     exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
-    filters=ClusterFilter
+    filters=ClusterFilter,
+    pagination=True
 )
 )
 class ClusterType(VLANGroupsMixin, NetBoxObjectType):
 class ClusterType(VLANGroupsMixin, NetBoxObjectType):
     type: Annotated["ClusterTypeType", strawberry.lazy('virtualization.graphql.types')] | None
     type: Annotated["ClusterTypeType", strawberry.lazy('virtualization.graphql.types')] | None
@@ -68,7 +69,8 @@ class ClusterType(VLANGroupsMixin, NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ClusterGroup,
     models.ClusterGroup,
     fields='__all__',
     fields='__all__',
-    filters=ClusterGroupFilter
+    filters=ClusterGroupFilter,
+    pagination=True
 )
 )
 class ClusterGroupType(VLANGroupsMixin, OrganizationalObjectType):
 class ClusterGroupType(VLANGroupsMixin, OrganizationalObjectType):
 
 
@@ -78,7 +80,8 @@ class ClusterGroupType(VLANGroupsMixin, OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.ClusterType,
     models.ClusterType,
     fields='__all__',
     fields='__all__',
-    filters=ClusterTypeFilter
+    filters=ClusterTypeFilter,
+    pagination=True
 )
 )
 class ClusterTypeType(OrganizationalObjectType):
 class ClusterTypeType(OrganizationalObjectType):
 
 
@@ -88,7 +91,8 @@ class ClusterTypeType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualMachine,
     models.VirtualMachine,
     fields='__all__',
     fields='__all__',
-    filters=VirtualMachineFilter
+    filters=VirtualMachineFilter,
+    pagination=True
 )
 )
 class VirtualMachineType(ConfigContextMixin, ContactsMixin, NetBoxObjectType):
 class VirtualMachineType(ConfigContextMixin, ContactsMixin, NetBoxObjectType):
     interface_count: BigInt
     interface_count: BigInt
@@ -112,7 +116,8 @@ class VirtualMachineType(ConfigContextMixin, ContactsMixin, NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VMInterface,
     models.VMInterface,
     fields='__all__',
     fields='__all__',
-    filters=VMInterfaceFilter
+    filters=VMInterfaceFilter,
+    pagination=True
 )
 )
 class VMInterfaceType(IPAddressesMixin, ComponentType):
 class VMInterfaceType(IPAddressesMixin, ComponentType):
     _name: str
     _name: str
@@ -134,7 +139,8 @@ class VMInterfaceType(IPAddressesMixin, ComponentType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.VirtualDisk,
     models.VirtualDisk,
     fields='__all__',
     fields='__all__',
-    filters=VirtualDiskFilter
+    filters=VirtualDiskFilter,
+    pagination=True
 )
 )
 class VirtualDiskType(ComponentType):
 class VirtualDiskType(ComponentType):
     pass
     pass

+ 20 - 10
netbox/vpn/graphql/types.py

@@ -32,7 +32,8 @@ __all__ = (
 @strawberry_django.type(
 @strawberry_django.type(
     models.TunnelGroup,
     models.TunnelGroup,
     fields='__all__',
     fields='__all__',
-    filters=TunnelGroupFilter
+    filters=TunnelGroupFilter,
+    pagination=True
 )
 )
 class TunnelGroupType(OrganizationalObjectType):
 class TunnelGroupType(OrganizationalObjectType):
 
 
@@ -42,7 +43,8 @@ class TunnelGroupType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.TunnelTermination,
     models.TunnelTermination,
     fields='__all__',
     fields='__all__',
-    filters=TunnelTerminationFilter
+    filters=TunnelTerminationFilter,
+    pagination=True
 )
 )
 class TunnelTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
 class TunnelTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
     tunnel: Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]
     tunnel: Annotated["TunnelType", strawberry.lazy('vpn.graphql.types')]
@@ -53,7 +55,8 @@ class TunnelTerminationType(CustomFieldsMixin, TagsMixin, ObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.Tunnel,
     models.Tunnel,
     fields='__all__',
     fields='__all__',
-    filters=TunnelFilter
+    filters=TunnelFilter,
+    pagination=True
 )
 )
 class TunnelType(NetBoxObjectType):
 class TunnelType(NetBoxObjectType):
     group: Annotated["TunnelGroupType", strawberry.lazy('vpn.graphql.types')] | None
     group: Annotated["TunnelGroupType", strawberry.lazy('vpn.graphql.types')] | None
@@ -66,7 +69,8 @@ class TunnelType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IKEProposal,
     models.IKEProposal,
     fields='__all__',
     fields='__all__',
-    filters=IKEProposalFilter
+    filters=IKEProposalFilter,
+    pagination=True
 )
 )
 class IKEProposalType(OrganizationalObjectType):
 class IKEProposalType(OrganizationalObjectType):
 
 
@@ -76,7 +80,8 @@ class IKEProposalType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IKEPolicy,
     models.IKEPolicy,
     fields='__all__',
     fields='__all__',
-    filters=IKEPolicyFilter
+    filters=IKEPolicyFilter,
+    pagination=True
 )
 )
 class IKEPolicyType(OrganizationalObjectType):
 class IKEPolicyType(OrganizationalObjectType):
 
 
@@ -87,7 +92,8 @@ class IKEPolicyType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IPSecProposal,
     models.IPSecProposal,
     fields='__all__',
     fields='__all__',
-    filters=IPSecProposalFilter
+    filters=IPSecProposalFilter,
+    pagination=True
 )
 )
 class IPSecProposalType(OrganizationalObjectType):
 class IPSecProposalType(OrganizationalObjectType):
 
 
@@ -97,7 +103,8 @@ class IPSecProposalType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IPSecPolicy,
     models.IPSecPolicy,
     fields='__all__',
     fields='__all__',
-    filters=IPSecPolicyFilter
+    filters=IPSecPolicyFilter,
+    pagination=True
 )
 )
 class IPSecPolicyType(OrganizationalObjectType):
 class IPSecPolicyType(OrganizationalObjectType):
 
 
@@ -108,7 +115,8 @@ class IPSecPolicyType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.IPSecProfile,
     models.IPSecProfile,
     fields='__all__',
     fields='__all__',
-    filters=IPSecProfileFilter
+    filters=IPSecProfileFilter,
+    pagination=True
 )
 )
 class IPSecProfileType(OrganizationalObjectType):
 class IPSecProfileType(OrganizationalObjectType):
     ike_policy: Annotated["IKEPolicyType", strawberry.lazy('vpn.graphql.types')]
     ike_policy: Annotated["IKEPolicyType", strawberry.lazy('vpn.graphql.types')]
@@ -120,7 +128,8 @@ class IPSecProfileType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.L2VPN,
     models.L2VPN,
     fields='__all__',
     fields='__all__',
-    filters=L2VPNFilter
+    filters=L2VPNFilter,
+    pagination=True
 )
 )
 class L2VPNType(ContactsMixin, NetBoxObjectType):
 class L2VPNType(ContactsMixin, NetBoxObjectType):
     tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
     tenant: Annotated["TenantType", strawberry.lazy('tenancy.graphql.types')] | None
@@ -133,7 +142,8 @@ class L2VPNType(ContactsMixin, NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.L2VPNTermination,
     models.L2VPNTermination,
     exclude=['assigned_object_type', 'assigned_object_id'],
     exclude=['assigned_object_type', 'assigned_object_id'],
-    filters=L2VPNTerminationFilter
+    filters=L2VPNTerminationFilter,
+    pagination=True
 )
 )
 class L2VPNTerminationType(NetBoxObjectType):
 class L2VPNTerminationType(NetBoxObjectType):
     l2vpn: Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]
     l2vpn: Annotated["L2VPNType", strawberry.lazy('vpn.graphql.types')]

+ 6 - 3
netbox/wireless/graphql/types.py

@@ -22,7 +22,8 @@ __all__ = (
 @strawberry_django.type(
 @strawberry_django.type(
     models.WirelessLANGroup,
     models.WirelessLANGroup,
     fields='__all__',
     fields='__all__',
-    filters=WirelessLANGroupFilter
+    filters=WirelessLANGroupFilter,
+    pagination=True
 )
 )
 class WirelessLANGroupType(OrganizationalObjectType):
 class WirelessLANGroupType(OrganizationalObjectType):
     parent: Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')] | None
     parent: Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')] | None
@@ -34,7 +35,8 @@ class WirelessLANGroupType(OrganizationalObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.WirelessLAN,
     models.WirelessLAN,
     exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
     exclude=['scope_type', 'scope_id', '_location', '_region', '_site', '_site_group'],
-    filters=WirelessLANFilter
+    filters=WirelessLANFilter,
+    pagination=True
 )
 )
 class WirelessLANType(NetBoxObjectType):
 class WirelessLANType(NetBoxObjectType):
     group: Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')] | None
     group: Annotated["WirelessLANGroupType", strawberry.lazy('wireless.graphql.types')] | None
@@ -56,7 +58,8 @@ class WirelessLANType(NetBoxObjectType):
 @strawberry_django.type(
 @strawberry_django.type(
     models.WirelessLink,
     models.WirelessLink,
     fields='__all__',
     fields='__all__',
-    filters=WirelessLinkFilter
+    filters=WirelessLinkFilter,
+    pagination=True
 )
 )
 class WirelessLinkType(NetBoxObjectType):
 class WirelessLinkType(NetBoxObjectType):
     interface_a: Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]
     interface_a: Annotated["InterfaceType", strawberry.lazy('dcim.graphql.types')]