From dd11bdafee581ba3feb6ab9ac5ed643dfd1f52bd Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 5 Dec 2025 15:19:34 -0500 Subject: [PATCH 1/6] Rename base filter classes & move to netbox.graphql.filters --- docs/plugins/development/migration-v4.md | 4 +- netbox/circuits/graphql/filter_mixins.py | 6 +- netbox/circuits/graphql/filters.py | 34 +++--- netbox/core/graphql/filter_mixins.py | 26 +---- netbox/core/graphql/filters.py | 15 +-- netbox/dcim/graphql/filter_mixins.py | 33 +++--- netbox/dcim/graphql/filters.py | 108 +++++++++--------- netbox/extras/graphql/filter_mixins.py | 14 +-- netbox/extras/graphql/filters.py | 37 +++--- netbox/ipam/graphql/filter_mixins.py | 4 +- netbox/ipam/graphql/filters.py | 42 +++---- netbox/netbox/graphql/filter_mixins.py | 52 +-------- netbox/netbox/graphql/filters.py | 64 +++++++++++ netbox/tenancy/graphql/filter_mixins.py | 6 +- netbox/tenancy/graphql/filters.py | 19 ++- .../virtualization/graphql/filter_mixins.py | 6 +- netbox/virtualization/graphql/filters.py | 21 ++-- netbox/vpn/graphql/filters.py | 26 +++-- netbox/wireless/graphql/filter_mixins.py | 4 +- netbox/wireless/graphql/filters.py | 9 +- 20 files changed, 262 insertions(+), 268 deletions(-) create mode 100644 netbox/netbox/graphql/filters.py diff --git a/docs/plugins/development/migration-v4.md b/docs/plugins/development/migration-v4.md index bf7e720ac2e..4fa5ea752d6 100644 --- a/docs/plugins/development/migration-v4.md +++ b/docs/plugins/development/migration-v4.md @@ -332,7 +332,7 @@ import strawberry import strawberry_django from circuits import filtersets, models -from netbox.graphql.filter_mixins import autotype_decorator, BaseFilterMixin +from netbox.graphql.filter_mixins import autotype_decorator, BaseFilter __all__ = ( 'CircuitFilter', @@ -341,7 +341,7 @@ __all__ = ( @strawberry_django.filter(models.Circuit, lookups=True) @autotype_decorator(filtersets.CircuitFilterSet) -class CircuitFilter(BaseFilterMixin): +class CircuitFilter(BaseFilter): pass ``` diff --git a/netbox/circuits/graphql/filter_mixins.py b/netbox/circuits/graphql/filter_mixins.py index 3ae6fa82ea7..0781288cc98 100644 --- a/netbox/circuits/graphql/filter_mixins.py +++ b/netbox/circuits/graphql/filter_mixins.py @@ -4,16 +4,16 @@ import strawberry import strawberry_django -from netbox.graphql.filter_mixins import OrganizationalModelFilterMixin +from netbox.graphql.filters import OrganizationalModelFilter if TYPE_CHECKING: from netbox.graphql.enums import ColorEnum __all__ = ( - 'BaseCircuitTypeFilterMixin', + 'BaseCircuitTypeFilter', ) @dataclass -class BaseCircuitTypeFilterMixin(OrganizationalModelFilterMixin): +class BaseCircuitTypeFilter(OrganizationalModelFilter): color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field() diff --git a/netbox/circuits/graphql/filters.py b/netbox/circuits/graphql/filters.py index 25cb8092df5..933fd1c6018 100644 --- a/netbox/circuits/graphql/filters.py +++ b/netbox/circuits/graphql/filters.py @@ -7,17 +7,13 @@ from strawberry_django import BaseFilterLookup, FilterLookup, DateFilterLookup from circuits import models -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin +from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from dcim.graphql.filter_mixins import CabledObjectModelFilterMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin -from netbox.graphql.filter_mixins import ( - DistanceFilterMixin, - ImageAttachmentFilterMixin, - OrganizationalModelFilterMixin, - PrimaryModelFilterMixin, -) +from netbox.graphql.filter_mixins import DistanceFilterMixin, ImageAttachmentFilterMixin +from netbox.graphql.filters import ChangeLoggedModelFilter, OrganizationalModelFilter, PrimaryModelFilter from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin -from .filter_mixins import BaseCircuitTypeFilterMixin +from .filter_mixins import BaseCircuitTypeFilter if TYPE_CHECKING: from core.graphql.filters import ContentTypeFilter @@ -46,7 +42,7 @@ class CircuitTerminationFilter( BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, - ChangeLogFilterMixin, + ChangeLoggedModelFilter, CabledObjectModelFilterMixin, ): circuit: Annotated['CircuitFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( @@ -95,7 +91,7 @@ class CircuitFilter( ImageAttachmentFilterMixin, DistanceFilterMixin, TenancyFilterMixin, - PrimaryModelFilterMixin + PrimaryModelFilter ): cid: FilterLookup[str] | None = strawberry_django.filter_field() provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( @@ -124,18 +120,18 @@ class CircuitFilter( @strawberry_django.filter_type(models.CircuitType, lookups=True) -class CircuitTypeFilter(BaseCircuitTypeFilterMixin): +class CircuitTypeFilter(BaseCircuitTypeFilter): pass @strawberry_django.filter_type(models.CircuitGroup, lookups=True) -class CircuitGroupFilter(TenancyFilterMixin, OrganizationalModelFilterMixin): +class CircuitGroupFilter(TenancyFilterMixin, OrganizationalModelFilter): pass @strawberry_django.filter_type(models.CircuitGroupAssignment, lookups=True) class CircuitGroupAssignmentFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin + BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter ): member_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -151,7 +147,7 @@ class CircuitGroupAssignmentFilter( @strawberry_django.filter_type(models.Provider, lookups=True) -class ProviderFilter(ContactFilterMixin, PrimaryModelFilterMixin): +class ProviderFilter(ContactFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() asns: Annotated['ASNFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field() @@ -161,7 +157,7 @@ class ProviderFilter(ContactFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.ProviderAccount, lookups=True) -class ProviderAccountFilter(ContactFilterMixin, PrimaryModelFilterMixin): +class ProviderAccountFilter(ContactFilterMixin, PrimaryModelFilter): provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -171,7 +167,7 @@ class ProviderAccountFilter(ContactFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.ProviderNetwork, lookups=True) -class ProviderNetworkFilter(PrimaryModelFilterMixin): +class ProviderNetworkFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() provider: Annotated['ProviderFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -181,12 +177,12 @@ class ProviderNetworkFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.VirtualCircuitType, lookups=True) -class VirtualCircuitTypeFilter(BaseCircuitTypeFilterMixin): +class VirtualCircuitTypeFilter(BaseCircuitTypeFilter): pass @strawberry_django.filter_type(models.VirtualCircuit, lookups=True) -class VirtualCircuitFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class VirtualCircuitFilter(TenancyFilterMixin, PrimaryModelFilter): cid: FilterLookup[str] | None = strawberry_django.filter_field() provider_network: Annotated['ProviderNetworkFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -210,7 +206,7 @@ class VirtualCircuitFilter(TenancyFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.VirtualCircuitTermination, lookups=True) class VirtualCircuitTerminationFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin + BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter ): virtual_circuit: Annotated['VirtualCircuitFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( strawberry_django.filter_field() diff --git a/netbox/core/graphql/filter_mixins.py b/netbox/core/graphql/filter_mixins.py index 4d1f4fad5ce..ed14108260a 100644 --- a/netbox/core/graphql/filter_mixins.py +++ b/netbox/core/graphql/filter_mixins.py @@ -1,37 +1,19 @@ from dataclasses import dataclass -from datetime import datetime -from typing import Annotated, TYPE_CHECKING -import strawberry import strawberry_django from strawberry import ID -from strawberry_django import FilterLookup, DatetimeFilterLookup - -if TYPE_CHECKING: - from .filters import * +from strawberry_django import FilterLookup __all__ = ( - 'BaseFilterMixin', + 'BaseFilter', 'BaseObjectTypeFilterMixin', - 'ChangeLogFilterMixin', ) # @strawberry.input -class BaseFilterMixin: ... - - -@dataclass -class BaseObjectTypeFilterMixin(BaseFilterMixin): - id: FilterLookup[ID] | None = strawberry_django.filter_field() +class BaseFilter: ... @dataclass -class ChangeLogFilterMixin(BaseFilterMixin): +class BaseObjectTypeFilterMixin(BaseFilter): id: FilterLookup[ID] | None = strawberry_django.filter_field() - # TODO: "changelog" is not a valid field name; needs to be updated for ObjectChange - changelog: Annotated['ObjectChangeFilter', strawberry.lazy('core.graphql.filters')] | None = ( - strawberry_django.filter_field() - ) - created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() - last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() diff --git a/netbox/core/graphql/filters.py b/netbox/core/graphql/filters.py index b61917c7edb..aa908cc655e 100644 --- a/netbox/core/graphql/filters.py +++ b/netbox/core/graphql/filters.py @@ -8,8 +8,8 @@ from strawberry_django import BaseFilterLookup, DatetimeFilterLookup, FilterLookup from core import models -from core.graphql.filter_mixins import BaseFilterMixin -from netbox.graphql.filter_mixins import PrimaryModelFilterMixin +from core.graphql.filter_mixins import BaseObjectTypeFilterMixin +from netbox.graphql.filters import PrimaryModelFilter from .enums import * if TYPE_CHECKING: @@ -25,8 +25,7 @@ @strawberry_django.filter_type(models.DataFile, lookups=True) -class DataFileFilter(BaseFilterMixin): - id: FilterLookup[ID] | None = strawberry_django.filter_field() +class DataFileFilter(BaseObjectTypeFilterMixin): created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() source: Annotated['DataSourceFilter', strawberry.lazy('core.graphql.filters')] | None = ( @@ -41,7 +40,7 @@ class DataFileFilter(BaseFilterMixin): @strawberry_django.filter_type(models.DataSource, lookups=True) -class DataSourceFilter(PrimaryModelFilterMixin): +class DataSourceFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() type: FilterLookup[str] | None = strawberry_django.filter_field() source_url: FilterLookup[str] | None = strawberry_django.filter_field() @@ -60,8 +59,7 @@ class DataSourceFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.ObjectChange, lookups=True) -class ObjectChangeFilter(BaseFilterMixin): - id: FilterLookup[ID] | None = strawberry_django.filter_field() +class ObjectChangeFilter(BaseObjectTypeFilterMixin): time: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field() user_name: FilterLookup[str] | None = strawberry_django.filter_field() @@ -88,7 +86,6 @@ class ObjectChangeFilter(BaseFilterMixin): @strawberry_django.filter_type(DjangoContentType, lookups=True) -class ContentTypeFilter(BaseFilterMixin): - id: FilterLookup[ID] | None = strawberry_django.filter_field() +class ContentTypeFilter(BaseObjectTypeFilterMixin): app_label: FilterLookup[str] | None = strawberry_django.filter_field() model: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/dcim/graphql/filter_mixins.py b/netbox/dcim/graphql/filter_mixins.py index c05eec1f57f..a0a5355501c 100644 --- a/netbox/dcim/graphql/filter_mixins.py +++ b/netbox/dcim/graphql/filter_mixins.py @@ -6,9 +6,10 @@ from strawberry import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseFilterMixin, ChangeLogFilterMixin +from core.graphql.filter_mixins import BaseFilter from core.graphql.filters import ContentTypeFilter -from netbox.graphql.filter_mixins import NetBoxModelFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin +from netbox.graphql.filter_mixins import WeightFilterMixin +from netbox.graphql.filters import ChangeLoggedModelFilter, NetBoxModelFilter, PrimaryModelFilter from .enums import * if TYPE_CHECKING: @@ -19,19 +20,19 @@ __all__ = ( 'CabledObjectModelFilterMixin', - 'ComponentModelFilterMixin', - 'ComponentTemplateFilterMixin', + 'ComponentModelFilter', + 'ComponentTemplateFilter', 'InterfaceBaseFilterMixin', - 'ModularComponentModelFilterMixin', - 'ModularComponentTemplateFilterMixin', - 'RackBaseFilterMixin', + 'ModularComponentModelFilter', + 'ModularComponentTemplateFilter', + 'RackBaseFilter', 'RenderConfigFilterMixin', 'ScopedFilterMixin', ) @dataclass -class ScopedFilterMixin(BaseFilterMixin): +class ScopedFilterMixin(BaseFilter): scope_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -39,7 +40,7 @@ class ScopedFilterMixin(BaseFilterMixin): @dataclass -class ComponentModelFilterMixin(NetBoxModelFilterMixin): +class ComponentModelFilter(NetBoxModelFilter): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() device_id: ID | None = strawberry_django.filter_field() name: FilterLookup[str] | None = strawberry_django.filter_field() @@ -48,7 +49,7 @@ class ComponentModelFilterMixin(NetBoxModelFilterMixin): @dataclass -class ModularComponentModelFilterMixin(ComponentModelFilterMixin): +class ModularComponentModelFilter(ComponentModelFilter): module: Annotated['ModuleFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() module_id: ID | None = strawberry_django.filter_field() inventory_items: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( @@ -57,7 +58,7 @@ class ModularComponentModelFilterMixin(ComponentModelFilterMixin): @dataclass -class CabledObjectModelFilterMixin(BaseFilterMixin): +class CabledObjectModelFilterMixin(BaseFilter): cable: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() cable_id: ID | None = strawberry_django.filter_field() cable_end: ( @@ -67,7 +68,7 @@ class CabledObjectModelFilterMixin(BaseFilterMixin): @dataclass -class ComponentTemplateFilterMixin(ChangeLogFilterMixin): +class ComponentTemplateFilter(ChangeLoggedModelFilter): device_type: Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -78,14 +79,14 @@ class ComponentTemplateFilterMixin(ChangeLogFilterMixin): @dataclass -class ModularComponentTemplateFilterMixin(ComponentTemplateFilterMixin): +class ModularComponentTemplateFilter(ComponentTemplateFilter): module_type: Annotated['ModuleTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class RenderConfigFilterMixin(BaseFilterMixin): +class RenderConfigFilterMixin(BaseFilter): config_template: Annotated['ConfigTemplateFilter', strawberry.lazy('extras.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -93,7 +94,7 @@ class RenderConfigFilterMixin(BaseFilterMixin): @dataclass -class InterfaceBaseFilterMixin(BaseFilterMixin): +class InterfaceBaseFilterMixin(BaseFilter): enabled: FilterLookup[bool] | None = strawberry_django.filter_field() mtu: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() @@ -124,7 +125,7 @@ class InterfaceBaseFilterMixin(BaseFilterMixin): @dataclass -class RackBaseFilterMixin(WeightFilterMixin, PrimaryModelFilterMixin): +class RackBaseFilter(WeightFilterMixin, PrimaryModelFilter): width: BaseFilterLookup[Annotated['RackWidthEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/dcim/graphql/filters.py b/netbox/dcim/graphql/filters.py index 1c99beedbec..c54673fa872 100644 --- a/netbox/dcim/graphql/filters.py +++ b/netbox/dcim/graphql/filters.py @@ -6,29 +6,25 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, ComparisonFilterLookup, FilterLookup -from core.graphql.filter_mixins import ChangeLogFilterMixin from dcim import models from dcim.constants import * from dcim.graphql.enums import InterfaceKindEnum from extras.graphql.filter_mixins import ConfigContextFilterMixin -from netbox.graphql.filter_mixins import ( - PrimaryModelFilterMixin, - OrganizationalModelFilterMixin, - NestedGroupModelFilterMixin, - ImageAttachmentFilterMixin, - WeightFilterMixin, +from netbox.graphql.filter_mixins import ImageAttachmentFilterMixin, WeightFilterMixin +from netbox.graphql.filters import ( + ChangeLoggedModelFilter, NestedGroupModelFilter, OrganizationalModelFilter, PrimaryModelFilter, ) from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin from virtualization.models import VMInterface from .filter_mixins import ( CabledObjectModelFilterMixin, - ComponentModelFilterMixin, - ComponentTemplateFilterMixin, + ComponentModelFilter, + ComponentTemplateFilter, InterfaceBaseFilterMixin, - ModularComponentModelFilterMixin, - ModularComponentTemplateFilterMixin, - RackBaseFilterMixin, + ModularComponentModelFilter, + ModularComponentTemplateFilter, + RackBaseFilter, RenderConfigFilterMixin, ) @@ -96,7 +92,7 @@ @strawberry_django.filter_type(models.Cable, lookups=True) -class CableFilter(PrimaryModelFilterMixin, TenancyFilterMixin): +class CableFilter(PrimaryModelFilter, TenancyFilterMixin): type: BaseFilterLookup[Annotated['CableTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -119,7 +115,7 @@ class CableFilter(PrimaryModelFilterMixin, TenancyFilterMixin): @strawberry_django.filter_type(models.CableTermination, lookups=True) -class CableTerminationFilter(ChangeLogFilterMixin): +class CableTerminationFilter(ChangeLoggedModelFilter): cable: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() cable_id: ID | None = strawberry_django.filter_field() cable_end: BaseFilterLookup[Annotated['CableEndEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( @@ -132,7 +128,7 @@ class CableTerminationFilter(ChangeLogFilterMixin): @strawberry_django.filter_type(models.ConsolePort, lookups=True) -class ConsolePortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin): +class ConsolePortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -142,14 +138,14 @@ class ConsolePortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilte @strawberry_django.filter_type(models.ConsolePortTemplate, lookups=True) -class ConsolePortTemplateFilter(ModularComponentTemplateFilterMixin): +class ConsolePortTemplateFilter(ModularComponentTemplateFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.ConsoleServerPort, lookups=True) -class ConsoleServerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin): +class ConsoleServerPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -159,7 +155,7 @@ class ConsoleServerPortFilter(ModularComponentModelFilterMixin, CabledObjectMode @strawberry_django.filter_type(models.ConsoleServerPortTemplate, lookups=True) -class ConsoleServerPortTemplateFilter(ModularComponentTemplateFilterMixin): +class ConsoleServerPortTemplateFilter(ModularComponentTemplateFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -172,7 +168,7 @@ class DeviceFilter( ImageAttachmentFilterMixin, RenderConfigFilterMixin, ConfigContextFilterMixin, - PrimaryModelFilterMixin, + PrimaryModelFilter, ): device_type: Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -285,7 +281,7 @@ class DeviceFilter( @strawberry_django.filter_type(models.DeviceBay, lookups=True) -class DeviceBayFilter(ComponentModelFilterMixin): +class DeviceBayFilter(ComponentModelFilter): installed_device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -293,12 +289,12 @@ class DeviceBayFilter(ComponentModelFilterMixin): @strawberry_django.filter_type(models.DeviceBayTemplate, lookups=True) -class DeviceBayTemplateFilter(ComponentTemplateFilterMixin): +class DeviceBayTemplateFilter(ComponentTemplateFilter): pass @strawberry_django.filter_type(models.InventoryItemTemplate, lookups=True) -class InventoryItemTemplateFilter(ComponentTemplateFilterMixin): +class InventoryItemTemplateFilter(ComponentTemplateFilter): parent: Annotated['InventoryItemTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -318,7 +314,7 @@ class InventoryItemTemplateFilter(ComponentTemplateFilterMixin): @strawberry_django.filter_type(models.DeviceRole, lookups=True) -class DeviceRoleFilter(OrganizationalModelFilterMixin, RenderConfigFilterMixin): +class DeviceRoleFilter(OrganizationalModelFilter, RenderConfigFilterMixin): color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -326,7 +322,7 @@ class DeviceRoleFilter(OrganizationalModelFilterMixin, RenderConfigFilterMixin): @strawberry_django.filter_type(models.DeviceType, lookups=True) -class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin): +class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilter, WeightFilterMixin): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -402,7 +398,7 @@ class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, Weig @strawberry_django.filter_type(models.FrontPort, lookups=True) -class FrontPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin): +class FrontPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -419,7 +415,7 @@ class FrontPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterM @strawberry_django.filter_type(models.FrontPortTemplate, lookups=True) -class FrontPortTemplateFilter(ModularComponentTemplateFilterMixin): +class FrontPortTemplateFilter(ModularComponentTemplateFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -436,7 +432,7 @@ class FrontPortTemplateFilter(ModularComponentTemplateFilterMixin): @strawberry_django.filter_type(models.MACAddress, lookups=True) -class MACAddressFilter(PrimaryModelFilterMixin): +class MACAddressFilter(PrimaryModelFilter): mac_address: FilterLookup[str] | None = strawberry_django.filter_field() assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -463,7 +459,7 @@ def primary(self, value: bool, prefix) -> Q: @strawberry_django.filter_type(models.Interface, lookups=True) -class InterfaceFilter(ModularComponentModelFilterMixin, InterfaceBaseFilterMixin, CabledObjectModelFilterMixin): +class InterfaceFilter(ModularComponentModelFilter, InterfaceBaseFilterMixin, CabledObjectModelFilterMixin): vcdcs: Annotated['VirtualDeviceContextFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -553,7 +549,7 @@ def kind( @strawberry_django.filter_type(models.InterfaceTemplate, lookups=True) -class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin): +class InterfaceTemplateFilter(ModularComponentTemplateFilter): type: BaseFilterLookup[Annotated['InterfaceTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -575,7 +571,7 @@ class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin): @strawberry_django.filter_type(models.InventoryItem, lookups=True) -class InventoryItemFilter(ComponentModelFilterMixin): +class InventoryItemFilter(ComponentModelFilter): parent: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -602,14 +598,14 @@ class InventoryItemFilter(ComponentModelFilterMixin): @strawberry_django.filter_type(models.InventoryItemRole, lookups=True) -class InventoryItemRoleFilter(OrganizationalModelFilterMixin): +class InventoryItemRoleFilter(OrganizationalModelFilter): color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.Location, lookups=True) -class LocationFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, NestedGroupModelFilterMixin): +class LocationFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, NestedGroupModelFilter): site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() site_id: ID | None = strawberry_django.filter_field() status: BaseFilterLookup[Annotated['LocationStatusEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( @@ -625,12 +621,12 @@ class LocationFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilt @strawberry_django.filter_type(models.Manufacturer, lookups=True) -class ManufacturerFilter(ContactFilterMixin, OrganizationalModelFilterMixin): +class ManufacturerFilter(ContactFilterMixin, OrganizationalModelFilter): pass @strawberry_django.filter_type(models.Module, lookups=True) -class ModuleFilter(PrimaryModelFilterMixin, ConfigContextFilterMixin): +class ModuleFilter(PrimaryModelFilter, ConfigContextFilterMixin): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() device_id: ID | None = strawberry_django.filter_field() module_bay: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( @@ -679,7 +675,7 @@ class ModuleFilter(PrimaryModelFilterMixin, ConfigContextFilterMixin): @strawberry_django.filter_type(models.ModuleBay, lookups=True) -class ModuleBayFilter(ModularComponentModelFilterMixin): +class ModuleBayFilter(ModularComponentModelFilter): parent: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -688,17 +684,17 @@ class ModuleBayFilter(ModularComponentModelFilterMixin): @strawberry_django.filter_type(models.ModuleBayTemplate, lookups=True) -class ModuleBayTemplateFilter(ModularComponentTemplateFilterMixin): +class ModuleBayTemplateFilter(ModularComponentTemplateFilter): position: FilterLookup[str] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.ModuleTypeProfile, lookups=True) -class ModuleTypeProfileFilter(PrimaryModelFilterMixin): +class ModuleTypeProfileFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.ModuleType, lookups=True) -class ModuleTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, WeightFilterMixin): +class ModuleTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilter, WeightFilterMixin): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -749,7 +745,7 @@ class ModuleTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilterMixin, Weig @strawberry_django.filter_type(models.Platform, lookups=True) -class PlatformFilter(OrganizationalModelFilterMixin): +class PlatformFilter(OrganizationalModelFilter): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -761,7 +757,7 @@ class PlatformFilter(OrganizationalModelFilterMixin): @strawberry_django.filter_type(models.PowerFeed, lookups=True) -class PowerFeedFilter(CabledObjectModelFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class PowerFeedFilter(CabledObjectModelFilterMixin, TenancyFilterMixin, PrimaryModelFilter): power_panel: Annotated['PowerPanelFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -796,7 +792,7 @@ class PowerFeedFilter(CabledObjectModelFilterMixin, TenancyFilterMixin, PrimaryM @strawberry_django.filter_type(models.PowerOutlet, lookups=True) -class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin): +class PowerOutletFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -816,7 +812,7 @@ class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilte @strawberry_django.filter_type(models.PowerOutletTemplate, lookups=True) -class PowerOutletTemplateFilter(ModularComponentModelFilterMixin): +class PowerOutletTemplateFilter(ModularComponentModelFilter): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -830,7 +826,7 @@ class PowerOutletTemplateFilter(ModularComponentModelFilterMixin): @strawberry_django.filter_type(models.PowerPanel, lookups=True) -class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryModelFilterMixin): +class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryModelFilter): site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() site_id: ID | None = strawberry_django.filter_field() location: Annotated['LocationFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( @@ -843,7 +839,7 @@ class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryMo @strawberry_django.filter_type(models.PowerPort, lookups=True) -class PowerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin): +class PowerPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): type: BaseFilterLookup[Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -856,7 +852,7 @@ class PowerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterM @strawberry_django.filter_type(models.PowerPortTemplate, lookups=True) -class PowerPortTemplateFilter(ModularComponentTemplateFilterMixin): +class PowerPortTemplateFilter(ModularComponentTemplateFilter): type: BaseFilterLookup[Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -869,7 +865,7 @@ class PowerPortTemplateFilter(ModularComponentTemplateFilterMixin): @strawberry_django.filter_type(models.RackType, lookups=True) -class RackTypeFilter(RackBaseFilterMixin): +class RackTypeFilter(RackBaseFilter): form_factor: BaseFilterLookup[Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -884,7 +880,7 @@ class RackTypeFilter(RackBaseFilterMixin): @strawberry_django.filter_type(models.Rack, lookups=True) -class RackFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, RackBaseFilterMixin): +class RackFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, RackBaseFilter): form_factor: BaseFilterLookup[Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -918,7 +914,7 @@ class RackFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMi @strawberry_django.filter_type(models.RackReservation, lookups=True) -class RackReservationFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class RackReservationFilter(TenancyFilterMixin, PrimaryModelFilter): rack: Annotated['RackFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() rack_id: ID | None = strawberry_django.filter_field() units: Annotated['IntegerArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( @@ -933,14 +929,14 @@ class RackReservationFilter(TenancyFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.RackRole, lookups=True) -class RackRoleFilter(OrganizationalModelFilterMixin): +class RackRoleFilter(OrganizationalModelFilter): color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.RearPort, lookups=True) -class RearPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin): +class RearPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -953,7 +949,7 @@ class RearPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMi @strawberry_django.filter_type(models.RearPortTemplate, lookups=True) -class RearPortTemplateFilter(ModularComponentTemplateFilterMixin): +class RearPortTemplateFilter(ModularComponentTemplateFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -966,7 +962,7 @@ class RearPortTemplateFilter(ModularComponentTemplateFilterMixin): @strawberry_django.filter_type(models.Region, lookups=True) -class RegionFilter(ContactFilterMixin, NestedGroupModelFilterMixin): +class RegionFilter(ContactFilterMixin, NestedGroupModelFilter): prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -976,7 +972,7 @@ class RegionFilter(ContactFilterMixin, NestedGroupModelFilterMixin): @strawberry_django.filter_type(models.Site, lookups=True) -class SiteFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class SiteFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() status: BaseFilterLookup[Annotated['SiteStatusEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( @@ -1012,7 +1008,7 @@ class SiteFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMi @strawberry_django.filter_type(models.SiteGroup, lookups=True) -class SiteGroupFilter(ContactFilterMixin, NestedGroupModelFilterMixin): +class SiteGroupFilter(ContactFilterMixin, NestedGroupModelFilter): prefixes: Annotated['PrefixFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -1022,7 +1018,7 @@ class SiteGroupFilter(ContactFilterMixin, NestedGroupModelFilterMixin): @strawberry_django.filter_type(models.VirtualChassis, lookups=True) -class VirtualChassisFilter(PrimaryModelFilterMixin): +class VirtualChassisFilter(PrimaryModelFilter): master: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() master_id: ID | None = strawberry_django.filter_field() name: FilterLookup[str] | None = strawberry_django.filter_field() @@ -1034,7 +1030,7 @@ class VirtualChassisFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.VirtualDeviceContext, lookups=True) -class VirtualDeviceContextFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class VirtualDeviceContextFilter(TenancyFilterMixin, PrimaryModelFilter): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() device_id: ID | None = strawberry_django.filter_field() name: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/extras/graphql/filter_mixins.py b/netbox/extras/graphql/filter_mixins.py index 7e9a970f26e..75a4c548c73 100644 --- a/netbox/extras/graphql/filter_mixins.py +++ b/netbox/extras/graphql/filter_mixins.py @@ -5,7 +5,7 @@ import strawberry_django from strawberry_django import FilterLookup -from core.graphql.filter_mixins import BaseFilterMixin +from core.graphql.filter_mixins import BaseFilter if TYPE_CHECKING: from netbox.graphql.filter_lookups import JSONFilter @@ -16,37 +16,37 @@ 'JournalEntriesFilterMixin', 'TagsFilterMixin', 'ConfigContextFilterMixin', - 'TagBaseFilterMixin', + 'TagBaseFilter', ) @dataclass -class CustomFieldsFilterMixin(BaseFilterMixin): +class CustomFieldsFilterMixin(BaseFilter): custom_field_data: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @dataclass -class JournalEntriesFilterMixin(BaseFilterMixin): +class JournalEntriesFilterMixin(BaseFilter): journal_entries: Annotated['JournalEntryFilter', strawberry.lazy('extras.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class TagsFilterMixin(BaseFilterMixin): +class TagsFilterMixin(BaseFilter): tags: Annotated['TagFilter', strawberry.lazy('extras.graphql.filters')] | None = strawberry_django.filter_field() @dataclass -class ConfigContextFilterMixin(BaseFilterMixin): +class ConfigContextFilterMixin(BaseFilter): local_context_data: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @dataclass -class TagBaseFilterMixin(BaseFilterMixin): +class TagBaseFilter(BaseFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/extras/graphql/filters.py b/netbox/extras/graphql/filters.py index 724c5342122..a21319b29d8 100644 --- a/netbox/extras/graphql/filters.py +++ b/netbox/extras/graphql/filters.py @@ -5,10 +5,11 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin +from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from extras import models -from extras.graphql.filter_mixins import TagBaseFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin -from netbox.graphql.filter_mixins import PrimaryModelFilterMixin, SyncedDataFilterMixin +from extras.graphql.filter_mixins import TagBaseFilter, CustomFieldsFilterMixin, TagsFilterMixin +from netbox.graphql.filter_mixins import SyncedDataFilterMixin +from netbox.graphql.filters import ChangeLoggedModelFilter, PrimaryModelFilter if TYPE_CHECKING: from core.graphql.filters import ContentTypeFilter @@ -42,7 +43,7 @@ @strawberry_django.filter_type(models.ConfigContext, lookups=True) -class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin): +class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() @@ -99,14 +100,14 @@ class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, Chan @strawberry_django.filter_type(models.ConfigContextProfile, lookups=True) -class ConfigContextProfileFilter(SyncedDataFilterMixin, PrimaryModelFilterMixin): +class ConfigContextProfileFilter(SyncedDataFilterMixin, PrimaryModelFilter): name: FilterLookup[str] = strawberry_django.filter_field() description: FilterLookup[str] = strawberry_django.filter_field() tags: Annotated['TagFilter', strawberry.lazy('extras.graphql.filters')] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.ConfigTemplate, lookups=True) -class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin): +class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() template_code: FilterLookup[str] | None = strawberry_django.filter_field() @@ -120,7 +121,7 @@ class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, Cha @strawberry_django.filter_type(models.CustomField, lookups=True) -class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['CustomFieldTypeEnum', strawberry.lazy('extras.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -179,7 +180,7 @@ class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): @strawberry_django.filter_type(models.CustomFieldChoiceSet, lookups=True) -class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() base_choices: ( @@ -194,7 +195,7 @@ class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin @strawberry_django.filter_type(models.CustomLink, lookups=True) -class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() enabled: FilterLookup[bool] | None = strawberry_django.filter_field() link_text: FilterLookup[str] | None = strawberry_django.filter_field() @@ -212,7 +213,7 @@ class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): @strawberry_django.filter_type(models.ExportTemplate, lookups=True) -class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLogFilterMixin): +class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() template_code: FilterLookup[str] | None = strawberry_django.filter_field() @@ -226,7 +227,7 @@ class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, Cha @strawberry_django.filter_type(models.ImageAttachment, lookups=True) -class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -241,7 +242,7 @@ class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): @strawberry_django.filter_type(models.JournalEntry, lookups=True) -class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin): +class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -257,7 +258,7 @@ class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, Tag @strawberry_django.filter_type(models.NotificationGroup, lookups=True) -class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() groups: Annotated['GroupFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field() @@ -265,7 +266,7 @@ class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): @strawberry_django.filter_type(models.SavedFilter, lookups=True) -class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() @@ -282,7 +283,7 @@ class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): @strawberry_django.filter_type(models.TableConfig, lookups=True) -class TableConfigFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class TableConfigFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field() @@ -295,7 +296,7 @@ class TableConfigFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): @strawberry_django.filter_type(models.Tag, lookups=True) -class TagFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin, TagBaseFilterMixin): +class TagFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter, TagBaseFilter): color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -303,7 +304,7 @@ class TagFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin, TagBaseFilterMi @strawberry_django.filter_type(models.Webhook, lookups=True) -class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin): +class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() payload_url: FilterLookup[str] | None = strawberry_django.filter_field() @@ -324,7 +325,7 @@ class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilt @strawberry_django.filter_type(models.EventRule, lookups=True) -class EventRuleFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin): +class EventRuleFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() event_types: Annotated['StringArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( diff --git a/netbox/ipam/graphql/filter_mixins.py b/netbox/ipam/graphql/filter_mixins.py index 511850285a2..07589cdf5d8 100644 --- a/netbox/ipam/graphql/filter_mixins.py +++ b/netbox/ipam/graphql/filter_mixins.py @@ -4,7 +4,7 @@ import strawberry import strawberry_django -from core.graphql.filter_mixins import BaseFilterMixin +from core.graphql.filter_mixins import BaseFilter if TYPE_CHECKING: from netbox.graphql.filter_lookups import IntegerLookup @@ -16,7 +16,7 @@ @dataclass -class ServiceBaseFilterMixin(BaseFilterMixin): +class ServiceBaseFilterMixin(BaseFilter): protocol: Annotated['ServiceProtocolEnum', strawberry.lazy('ipam.graphql.enums')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/ipam/graphql/filters.py b/netbox/ipam/graphql/filters.py index 67d7a723d42..b41a0dab8e3 100644 --- a/netbox/ipam/graphql/filters.py +++ b/netbox/ipam/graphql/filters.py @@ -9,12 +9,14 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup, DateFilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin +from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from dcim.graphql.filter_mixins import ScopedFilterMixin from dcim.models import Device from ipam import models from ipam.graphql.filter_mixins import ServiceBaseFilterMixin -from netbox.graphql.filter_mixins import NetBoxModelFilterMixin, OrganizationalModelFilterMixin, PrimaryModelFilterMixin +from netbox.graphql.filters import ( + ChangeLoggedModelFilter, NetBoxModelFilter, OrganizationalModelFilter, PrimaryModelFilter, +) from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin from virtualization.models import VMInterface @@ -49,7 +51,7 @@ @strawberry_django.filter_type(models.ASN, lookups=True) -class ASNFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class ASNFilter(TenancyFilterMixin, PrimaryModelFilter): rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field() rir_id: ID | None = strawberry_django.filter_field() asn: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( @@ -64,7 +66,7 @@ class ASNFilter(TenancyFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.ASNRange, lookups=True) -class ASNRangeFilter(TenancyFilterMixin, OrganizationalModelFilterMixin): +class ASNRangeFilter(TenancyFilterMixin, OrganizationalModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field() @@ -78,7 +80,7 @@ class ASNRangeFilter(TenancyFilterMixin, OrganizationalModelFilterMixin): @strawberry_django.filter_type(models.Aggregate, lookups=True) -class AggregateFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class AggregateFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilter): prefix: FilterLookup[str] | None = strawberry_django.filter_field() rir: Annotated['RIRFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field() rir_id: ID | None = strawberry_django.filter_field() @@ -111,7 +113,7 @@ def family( @strawberry_django.filter_type(models.FHRPGroup, lookups=True) -class FHRPGroupFilter(PrimaryModelFilterMixin): +class FHRPGroupFilter(PrimaryModelFilter): group_id: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @@ -129,7 +131,7 @@ class FHRPGroupFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.FHRPGroupAssignment, lookups=True) -class FHRPGroupAssignmentFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): +class FHRPGroupAssignmentFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): interface_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -168,7 +170,7 @@ def filter_device(self, field, value, prefix) -> Q: @strawberry_django.filter_type(models.IPAddress, lookups=True) -class IPAddressFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class IPAddressFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilter): address: FilterLookup[str] | None = strawberry_django.filter_field() vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field() vrf_id: ID | None = strawberry_django.filter_field() @@ -219,7 +221,7 @@ def family( @strawberry_django.filter_type(models.IPRange, lookups=True) -class IPRangeFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class IPRangeFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilter): start_address: FilterLookup[str] | None = strawberry_django.filter_field() end_address: FilterLookup[str] | None = strawberry_django.filter_field() size: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( @@ -273,7 +275,7 @@ def contains(self, value: list[str], prefix) -> Q: @strawberry_django.filter_type(models.Prefix, lookups=True) -class PrefixFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class PrefixFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilter): prefix: FilterLookup[str] | None = strawberry_django.filter_field() vrf: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = strawberry_django.filter_field() vrf_id: ID | None = strawberry_django.filter_field() @@ -310,19 +312,19 @@ def family( @strawberry_django.filter_type(models.RIR, lookups=True) -class RIRFilter(OrganizationalModelFilterMixin): +class RIRFilter(OrganizationalModelFilter): is_private: FilterLookup[bool] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.Role, lookups=True) -class RoleFilter(OrganizationalModelFilterMixin): +class RoleFilter(OrganizationalModelFilter): weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.RouteTarget, lookups=True) -class RouteTargetFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class RouteTargetFilter(TenancyFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() importing_vrfs: Annotated['VRFFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -339,7 +341,7 @@ class RouteTargetFilter(TenancyFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.Service, lookups=True) -class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilterMixin): +class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -351,12 +353,12 @@ class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilt @strawberry_django.filter_type(models.ServiceTemplate, lookups=True) -class ServiceTemplateFilter(ServiceBaseFilterMixin, PrimaryModelFilterMixin): +class ServiceTemplateFilter(ServiceBaseFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.VLAN, lookups=True) -class VLANFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class VLANFilter(TenancyFilterMixin, PrimaryModelFilter): site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() site_id: ID | None = strawberry_django.filter_field() group: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( @@ -388,19 +390,19 @@ class VLANFilter(TenancyFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.VLANGroup, lookups=True) -class VLANGroupFilter(ScopedFilterMixin, OrganizationalModelFilterMixin): +class VLANGroupFilter(ScopedFilterMixin, OrganizationalModelFilter): vid_ranges: Annotated['IntegerRangeArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.VLANTranslationPolicy, lookups=True) -class VLANTranslationPolicyFilter(PrimaryModelFilterMixin): +class VLANTranslationPolicyFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.VLANTranslationRule, lookups=True) -class VLANTranslationRuleFilter(NetBoxModelFilterMixin): +class VLANTranslationRuleFilter(NetBoxModelFilter): policy: Annotated['VLANTranslationPolicyFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -415,7 +417,7 @@ class VLANTranslationRuleFilter(NetBoxModelFilterMixin): @strawberry_django.filter_type(models.VRF, lookups=True) -class VRFFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class VRFFilter(TenancyFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() rd: FilterLookup[str] | None = strawberry_django.filter_field() enforce_unique: FilterLookup[bool] | None = strawberry_django.filter_field() diff --git a/netbox/netbox/graphql/filter_mixins.py b/netbox/netbox/graphql/filter_mixins.py index cb9fcffe793..19340e63ff9 100644 --- a/netbox/netbox/graphql/filter_mixins.py +++ b/netbox/netbox/graphql/filter_mixins.py @@ -4,19 +4,13 @@ import strawberry import strawberry_django -from strawberry import ID from strawberry_django import BaseFilterLookup, FilterLookup, DatetimeFilterLookup -from core.graphql.filter_mixins import BaseFilterMixin, BaseObjectTypeFilterMixin, ChangeLogFilterMixin -from extras.graphql.filter_mixins import CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin +from core.graphql.filter_mixins import BaseFilter __all__ = ( 'DistanceFilterMixin', 'ImageAttachmentFilterMixin', - 'NestedGroupModelFilterMixin', - 'NetBoxModelFilterMixin', - 'OrganizationalModelFilterMixin', - 'PrimaryModelFilterMixin', 'SyncedDataFilterMixin', 'WeightFilterMixin', ) @@ -30,51 +24,15 @@ from extras.graphql.filters import * -class NetBoxModelFilterMixin( - ChangeLogFilterMixin, - CustomFieldsFilterMixin, - JournalEntriesFilterMixin, - TagsFilterMixin, - BaseObjectTypeFilterMixin, -): - pass - - -@dataclass -class NestedGroupModelFilterMixin(NetBoxModelFilterMixin): - name: FilterLookup[str] | None = strawberry_django.filter_field() - slug: FilterLookup[str] | None = strawberry_django.filter_field() - description: FilterLookup[str] | None = strawberry_django.filter_field() - parent_id: ID | None = strawberry_django.filter_field() - - -@dataclass -class OrganizationalModelFilterMixin( - ChangeLogFilterMixin, - CustomFieldsFilterMixin, - TagsFilterMixin, - BaseObjectTypeFilterMixin, -): - name: FilterLookup[str] | None = strawberry_django.filter_field() - slug: FilterLookup[str] | None = strawberry_django.filter_field() - description: FilterLookup[str] | None = strawberry_django.filter_field() - - -@dataclass -class PrimaryModelFilterMixin(NetBoxModelFilterMixin): - description: FilterLookup[str] | None = strawberry_django.filter_field() - comments: FilterLookup[str] | None = strawberry_django.filter_field() - - @dataclass -class ImageAttachmentFilterMixin(BaseFilterMixin): +class ImageAttachmentFilterMixin(BaseFilter): images: Annotated['ImageAttachmentFilter', strawberry.lazy('extras.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class WeightFilterMixin(BaseFilterMixin): +class WeightFilterMixin(BaseFilter): weight: FilterLookup[float] | None = strawberry_django.filter_field() weight_unit: BaseFilterLookup[Annotated['WeightUnitEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() @@ -82,7 +40,7 @@ class WeightFilterMixin(BaseFilterMixin): @dataclass -class SyncedDataFilterMixin(BaseFilterMixin): +class SyncedDataFilterMixin(BaseFilter): data_source: Annotated['DataSourceFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -97,7 +55,7 @@ class SyncedDataFilterMixin(BaseFilterMixin): @dataclass -class DistanceFilterMixin(BaseFilterMixin): +class DistanceFilterMixin(BaseFilter): distance: FilterLookup[float] | None = strawberry_django.filter_field() distance_unit: BaseFilterLookup[Annotated['DistanceUnitEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() diff --git a/netbox/netbox/graphql/filters.py b/netbox/netbox/graphql/filters.py new file mode 100644 index 00000000000..4b48b56a31e --- /dev/null +++ b/netbox/netbox/graphql/filters.py @@ -0,0 +1,64 @@ +from dataclasses import dataclass +from datetime import datetime +from typing import Annotated, TYPE_CHECKING + +import strawberry +import strawberry_django +from strawberry import ID +from strawberry_django import FilterLookup, DatetimeFilterLookup + +from core.graphql.filter_mixins import BaseFilter +from extras.graphql.filter_mixins import CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin + +if TYPE_CHECKING: + from .filters import * + +__all__ = ( + 'ChangeLoggedModelFilter', + 'NestedGroupModelFilter', + 'NetBoxModelFilter', + 'OrganizationalModelFilter', + 'PrimaryModelFilter', +) + + +@dataclass +class ChangeLoggedModelFilter(BaseFilter): + id: FilterLookup[ID] | None = strawberry_django.filter_field() + # TODO: "changelog" is not a valid field name; needs to be updated for ObjectChange + changelog: Annotated['ObjectChangeFilter', strawberry.lazy('core.graphql.filters')] | None = ( + strawberry_django.filter_field() + ) + created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() + last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() + + +class NetBoxModelFilter( + ChangeLoggedModelFilter, + CustomFieldsFilterMixin, + JournalEntriesFilterMixin, + TagsFilterMixin, + BaseFilter, +): + pass + + +@dataclass +class NestedGroupModelFilter(NetBoxModelFilter): + name: FilterLookup[str] | None = strawberry_django.filter_field() + slug: FilterLookup[str] | None = strawberry_django.filter_field() + description: FilterLookup[str] | None = strawberry_django.filter_field() + parent_id: ID | None = strawberry_django.filter_field() + + +@dataclass +class OrganizationalModelFilter(NetBoxModelFilter): + name: FilterLookup[str] | None = strawberry_django.filter_field() + slug: FilterLookup[str] | None = strawberry_django.filter_field() + description: FilterLookup[str] | None = strawberry_django.filter_field() + + +@dataclass +class PrimaryModelFilter(NetBoxModelFilter): + description: FilterLookup[str] | None = strawberry_django.filter_field() + comments: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/tenancy/graphql/filter_mixins.py b/netbox/tenancy/graphql/filter_mixins.py index 3a74d850a78..698b031e1cb 100644 --- a/netbox/tenancy/graphql/filter_mixins.py +++ b/netbox/tenancy/graphql/filter_mixins.py @@ -5,7 +5,7 @@ import strawberry_django from strawberry import ID -from core.graphql.filter_mixins import BaseFilterMixin +from core.graphql.filter_mixins import BaseFilter if TYPE_CHECKING: from netbox.graphql.filter_lookups import TreeNodeFilter @@ -18,14 +18,14 @@ @dataclass -class ContactFilterMixin(BaseFilterMixin): +class ContactFilterMixin(BaseFilter): contacts: Annotated['ContactAssignmentFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class TenancyFilterMixin(BaseFilterMixin): +class TenancyFilterMixin(BaseFilter): tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/tenancy/graphql/filters.py b/netbox/tenancy/graphql/filters.py index dbdbfd7503f..4c5eaff22b1 100644 --- a/netbox/tenancy/graphql/filters.py +++ b/netbox/tenancy/graphql/filters.py @@ -5,12 +5,9 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import ChangeLogFilterMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin -from netbox.graphql.filter_mixins import ( - NestedGroupModelFilterMixin, - OrganizationalModelFilterMixin, - PrimaryModelFilterMixin, +from netbox.graphql.filters import ( + ChangeLoggedModelFilter, NestedGroupModelFilter, OrganizationalModelFilter, PrimaryModelFilter, ) from tenancy import models from .filter_mixins import ContactFilterMixin @@ -57,7 +54,7 @@ @strawberry_django.filter_type(models.Tenant, lookups=True) -class TenantFilter(PrimaryModelFilterMixin, ContactFilterMixin): +class TenantFilter(PrimaryModelFilter, ContactFilterMixin): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() group: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( @@ -136,7 +133,7 @@ class TenantFilter(PrimaryModelFilterMixin, ContactFilterMixin): @strawberry_django.filter_type(models.TenantGroup, lookups=True) -class TenantGroupFilter(OrganizationalModelFilterMixin): +class TenantGroupFilter(OrganizationalModelFilter): parent: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -150,7 +147,7 @@ class TenantGroupFilter(OrganizationalModelFilterMixin): @strawberry_django.filter_type(models.Contact, lookups=True) -class ContactFilter(PrimaryModelFilterMixin): +class ContactFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() title: FilterLookup[str] | None = strawberry_django.filter_field() phone: FilterLookup[str] | None = strawberry_django.filter_field() @@ -166,19 +163,19 @@ class ContactFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.ContactRole, lookups=True) -class ContactRoleFilter(OrganizationalModelFilterMixin): +class ContactRoleFilter(OrganizationalModelFilter): pass @strawberry_django.filter_type(models.ContactGroup, lookups=True) -class ContactGroupFilter(NestedGroupModelFilterMixin): +class ContactGroupFilter(NestedGroupModelFilter): parent: Annotated['ContactGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.ContactAssignment, lookups=True) -class ContactAssignmentFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin): +class ContactAssignmentFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/virtualization/graphql/filter_mixins.py b/netbox/virtualization/graphql/filter_mixins.py index ed7a6cfb1f5..134db450644 100644 --- a/netbox/virtualization/graphql/filter_mixins.py +++ b/netbox/virtualization/graphql/filter_mixins.py @@ -6,18 +6,18 @@ from strawberry import ID from strawberry_django import FilterLookup -from netbox.graphql.filter_mixins import NetBoxModelFilterMixin +from netbox.graphql.filters import NetBoxModelFilter if TYPE_CHECKING: from .filters import VirtualMachineFilter __all__ = ( - 'VMComponentFilterMixin', + 'VMComponentFilter', ) @dataclass -class VMComponentFilterMixin(NetBoxModelFilterMixin): +class VMComponentFilter(NetBoxModelFilter): virtual_machine: Annotated['VirtualMachineFilter', strawberry.lazy('virtualization.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/virtualization/graphql/filters.py b/netbox/virtualization/graphql/filters.py index ad8e40ee561..c202ab30654 100644 --- a/netbox/virtualization/graphql/filters.py +++ b/netbox/virtualization/graphql/filters.py @@ -7,14 +7,11 @@ from dcim.graphql.filter_mixins import InterfaceBaseFilterMixin, RenderConfigFilterMixin, ScopedFilterMixin from extras.graphql.filter_mixins import ConfigContextFilterMixin -from netbox.graphql.filter_mixins import ( - ImageAttachmentFilterMixin, - OrganizationalModelFilterMixin, - PrimaryModelFilterMixin, -) +from netbox.graphql.filter_mixins import ImageAttachmentFilterMixin +from netbox.graphql.filters import OrganizationalModelFilter, PrimaryModelFilter from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin from virtualization import models -from virtualization.graphql.filter_mixins import VMComponentFilterMixin +from virtualization.graphql.filter_mixins import VMComponentFilter if TYPE_CHECKING: from .enums import * @@ -40,7 +37,7 @@ @strawberry_django.filter_type(models.Cluster, lookups=True) -class ClusterFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class ClusterFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() type: Annotated['ClusterTypeFilter', strawberry.lazy('virtualization.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -59,14 +56,14 @@ class ClusterFilter(ContactFilterMixin, ScopedFilterMixin, TenancyFilterMixin, P @strawberry_django.filter_type(models.ClusterGroup, lookups=True) -class ClusterGroupFilter(ContactFilterMixin, OrganizationalModelFilterMixin): +class ClusterGroupFilter(ContactFilterMixin, OrganizationalModelFilter): vlan_groups: Annotated['VLANGroupFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.ClusterType, lookups=True) -class ClusterTypeFilter(OrganizationalModelFilterMixin): +class ClusterTypeFilter(OrganizationalModelFilter): pass @@ -77,7 +74,7 @@ class VirtualMachineFilter( RenderConfigFilterMixin, ConfigContextFilterMixin, TenancyFilterMixin, - PrimaryModelFilterMixin, + PrimaryModelFilter, ): name: FilterLookup[str] | None = strawberry_django.filter_field() site: Annotated['SiteFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() @@ -138,7 +135,7 @@ class VirtualMachineFilter( @strawberry_django.filter_type(models.VMInterface, lookups=True) -class VMInterfaceFilter(VMComponentFilterMixin, InterfaceBaseFilterMixin): +class VMInterfaceFilter(VMComponentFilter, InterfaceBaseFilterMixin): ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -163,7 +160,7 @@ class VMInterfaceFilter(VMComponentFilterMixin, InterfaceBaseFilterMixin): @strawberry_django.filter_type(models.VirtualDisk, lookups=True) -class VirtualDiskFilter(VMComponentFilterMixin): +class VirtualDiskFilter(VMComponentFilter): size: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/vpn/graphql/filters.py b/netbox/vpn/graphql/filters.py index 403ece3b3e3..83963b66626 100644 --- a/netbox/vpn/graphql/filters.py +++ b/netbox/vpn/graphql/filters.py @@ -5,9 +5,11 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin, ChangeLogFilterMixin +from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin -from netbox.graphql.filter_mixins import NetBoxModelFilterMixin, OrganizationalModelFilterMixin, PrimaryModelFilterMixin +from netbox.graphql.filters import ( + ChangeLoggedModelFilter, NetBoxModelFilter, OrganizationalModelFilter, PrimaryModelFilter, +) from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin from vpn import models @@ -32,13 +34,13 @@ @strawberry_django.filter_type(models.TunnelGroup, lookups=True) -class TunnelGroupFilter(OrganizationalModelFilterMixin): +class TunnelGroupFilter(OrganizationalModelFilter): pass @strawberry_django.filter_type(models.TunnelTermination, lookups=True) class TunnelTerminationFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLogFilterMixin + BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter ): tunnel: Annotated['TunnelFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field() tunnel_id: ID | None = strawberry_django.filter_field() @@ -59,7 +61,7 @@ class TunnelTerminationFilter( @strawberry_django.filter_type(models.Tunnel, lookups=True) -class TunnelFilter(TenancyFilterMixin, PrimaryModelFilterMixin): +class TunnelFilter(TenancyFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() status: BaseFilterLookup[Annotated['TunnelStatusEnum', strawberry.lazy('vpn.graphql.enums')]] | None = ( strawberry_django.filter_field() @@ -85,7 +87,7 @@ class TunnelFilter(TenancyFilterMixin, PrimaryModelFilterMixin): @strawberry_django.filter_type(models.IKEProposal, lookups=True) -class IKEProposalFilter(PrimaryModelFilterMixin): +class IKEProposalFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() authentication_method: ( BaseFilterLookup[Annotated['AuthenticationMethodEnum', strawberry.lazy('vpn.graphql.enums')]] | None @@ -114,7 +116,7 @@ class IKEProposalFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.IKEPolicy, lookups=True) -class IKEPolicyFilter(PrimaryModelFilterMixin): +class IKEPolicyFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() version: BaseFilterLookup[Annotated['IKEVersionEnum', strawberry.lazy('vpn.graphql.enums')]] | None = ( strawberry_django.filter_field() @@ -129,7 +131,7 @@ class IKEPolicyFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.IPSecProposal, lookups=True) -class IPSecProposalFilter(PrimaryModelFilterMixin): +class IPSecProposalFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() encryption_algorithm: ( BaseFilterLookup[Annotated['EncryptionAlgorithmEnum', strawberry.lazy('vpn.graphql.enums')]] | None @@ -155,7 +157,7 @@ class IPSecProposalFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.IPSecPolicy, lookups=True) -class IPSecPolicyFilter(PrimaryModelFilterMixin): +class IPSecPolicyFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() proposals: Annotated['IPSecProposalFilter', strawberry.lazy('vpn.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -166,7 +168,7 @@ class IPSecPolicyFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.IPSecProfile, lookups=True) -class IPSecProfileFilter(PrimaryModelFilterMixin): +class IPSecProfileFilter(PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() mode: BaseFilterLookup[Annotated['IPSecModeEnum', strawberry.lazy('vpn.graphql.enums')]] | None = ( strawberry_django.filter_field() @@ -182,7 +184,7 @@ class IPSecProfileFilter(PrimaryModelFilterMixin): @strawberry_django.filter_type(models.L2VPN, lookups=True) -class L2VPNFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixin): +class L2VPNFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() type: BaseFilterLookup[Annotated['L2VPNTypeEnum', strawberry.lazy('vpn.graphql.enums')]] | None = ( @@ -206,7 +208,7 @@ class L2VPNFilter(ContactFilterMixin, TenancyFilterMixin, PrimaryModelFilterMixi @strawberry_django.filter_type(models.L2VPNTermination, lookups=True) -class L2VPNTerminationFilter(NetBoxModelFilterMixin): +class L2VPNTerminationFilter(NetBoxModelFilter): l2vpn: Annotated['L2VPNFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field() l2vpn_id: ID | None = strawberry_django.filter_field() assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( diff --git a/netbox/wireless/graphql/filter_mixins.py b/netbox/wireless/graphql/filter_mixins.py index 636bc8a52ce..966255aff29 100644 --- a/netbox/wireless/graphql/filter_mixins.py +++ b/netbox/wireless/graphql/filter_mixins.py @@ -5,7 +5,7 @@ import strawberry_django from strawberry_django import FilterLookup -from core.graphql.filter_mixins import BaseFilterMixin +from core.graphql.filter_mixins import BaseFilter if TYPE_CHECKING: from .enums import * @@ -16,7 +16,7 @@ @dataclass -class WirelessAuthenticationBaseFilterMixin(BaseFilterMixin): +class WirelessAuthenticationBaseFilterMixin(BaseFilter): auth_type: Annotated['WirelessAuthTypeEnum', strawberry.lazy('wireless.graphql.enums')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/wireless/graphql/filters.py b/netbox/wireless/graphql/filters.py index 342e078ed38..d676ca89ce9 100644 --- a/netbox/wireless/graphql/filters.py +++ b/netbox/wireless/graphql/filters.py @@ -6,7 +6,8 @@ from strawberry_django import BaseFilterLookup, FilterLookup from dcim.graphql.filter_mixins import ScopedFilterMixin -from netbox.graphql.filter_mixins import DistanceFilterMixin, PrimaryModelFilterMixin, NestedGroupModelFilterMixin +from netbox.graphql.filter_mixins import DistanceFilterMixin +from netbox.graphql.filters import PrimaryModelFilter, NestedGroupModelFilter from tenancy.graphql.filter_mixins import TenancyFilterMixin from wireless import models from .filter_mixins import WirelessAuthenticationBaseFilterMixin @@ -24,7 +25,7 @@ @strawberry_django.filter_type(models.WirelessLANGroup, lookups=True) -class WirelessLANGroupFilter(NestedGroupModelFilterMixin): +class WirelessLANGroupFilter(NestedGroupModelFilter): pass @@ -33,7 +34,7 @@ class WirelessLANFilter( WirelessAuthenticationBaseFilterMixin, ScopedFilterMixin, TenancyFilterMixin, - PrimaryModelFilterMixin + PrimaryModelFilter ): ssid: FilterLookup[str] | None = strawberry_django.filter_field() status: BaseFilterLookup[Annotated['WirelessLANStatusEnum', strawberry.lazy('wireless.graphql.enums')]] | None = ( @@ -52,7 +53,7 @@ class WirelessLinkFilter( WirelessAuthenticationBaseFilterMixin, DistanceFilterMixin, TenancyFilterMixin, - PrimaryModelFilterMixin + PrimaryModelFilter ): interface_a: Annotated['InterfaceFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() From 19e056bf8e4dd39dcaf0baa5bc87d6cf2c4714b6 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 5 Dec 2025 15:41:22 -0500 Subject: [PATCH 2/6] Rename BaseObjectTypeFilterMixin to BaseModelFilter; remove from mixins --- docs/plugins/development/migration-v4.md | 7 +++--- netbox/circuits/graphql/filters.py | 10 ++------ netbox/core/graphql/filter_mixins.py | 19 ---------------- netbox/core/graphql/filters.py | 9 ++++---- netbox/dcim/graphql/filter_mixins.py | 9 ++++---- netbox/extras/graphql/filter_mixins.py | 12 ++++------ netbox/extras/graphql/filters.py | 29 ++++++++++++------------ netbox/ipam/graphql/filter_mixins.py | 4 +--- netbox/ipam/graphql/filters.py | 3 +-- netbox/netbox/graphql/filter_mixins.py | 10 ++++---- netbox/netbox/graphql/filters.py | 12 ++++++---- netbox/tenancy/graphql/filter_mixins.py | 6 ++--- netbox/users/graphql/filters.py | 10 ++++---- netbox/vpn/graphql/filters.py | 5 +--- netbox/wireless/graphql/filter_mixins.py | 4 +--- 15 files changed, 54 insertions(+), 95 deletions(-) delete mode 100644 netbox/core/graphql/filter_mixins.py diff --git a/docs/plugins/development/migration-v4.md b/docs/plugins/development/migration-v4.md index 4fa5ea752d6..ee84950d26a 100644 --- a/docs/plugins/development/migration-v4.md +++ b/docs/plugins/development/migration-v4.md @@ -325,14 +325,14 @@ class CircuitTypeType(OrganizationalObjectType): ### Change filters.py -Strawberry currently doesn't directly support django-filter, so an explicit filters.py file will need to be created. NetBox includes a new `autotype_decorator` used to automatically wrap FilterSets to reduce the required code to a minimum. +Filter classes should inherit from `netbox.graphql.filters.BaseModelFilter`. ```python title="New" import strawberry import strawberry_django from circuits import filtersets, models -from netbox.graphql.filter_mixins import autotype_decorator, BaseFilter +from netbox.graphql.filters import BaseModelFilter __all__ = ( 'CircuitFilter', @@ -340,8 +340,7 @@ __all__ = ( @strawberry_django.filter(models.Circuit, lookups=True) -@autotype_decorator(filtersets.CircuitFilterSet) -class CircuitFilter(BaseFilter): +class CircuitFilter(BaseModelFilter): pass ``` diff --git a/netbox/circuits/graphql/filters.py b/netbox/circuits/graphql/filters.py index 933fd1c6018..25e267a5f7d 100644 --- a/netbox/circuits/graphql/filters.py +++ b/netbox/circuits/graphql/filters.py @@ -7,7 +7,6 @@ from strawberry_django import BaseFilterLookup, FilterLookup, DateFilterLookup from circuits import models -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from dcim.graphql.filter_mixins import CabledObjectModelFilterMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin from netbox.graphql.filter_mixins import DistanceFilterMixin, ImageAttachmentFilterMixin @@ -39,7 +38,6 @@ @strawberry_django.filter_type(models.CircuitTermination, lookups=True) class CircuitTerminationFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter, @@ -130,9 +128,7 @@ class CircuitGroupFilter(TenancyFilterMixin, OrganizationalModelFilter): @strawberry_django.filter_type(models.CircuitGroupAssignment, lookups=True) -class CircuitGroupAssignmentFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter -): +class CircuitGroupAssignmentFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): member_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -205,9 +201,7 @@ class VirtualCircuitFilter(TenancyFilterMixin, PrimaryModelFilter): @strawberry_django.filter_type(models.VirtualCircuitTermination, lookups=True) -class VirtualCircuitTerminationFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter -): +class VirtualCircuitTerminationFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): virtual_circuit: Annotated['VirtualCircuitFilter', strawberry.lazy('circuits.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/core/graphql/filter_mixins.py b/netbox/core/graphql/filter_mixins.py deleted file mode 100644 index ed14108260a..00000000000 --- a/netbox/core/graphql/filter_mixins.py +++ /dev/null @@ -1,19 +0,0 @@ -from dataclasses import dataclass - -import strawberry_django -from strawberry import ID -from strawberry_django import FilterLookup - -__all__ = ( - 'BaseFilter', - 'BaseObjectTypeFilterMixin', -) - - -# @strawberry.input -class BaseFilter: ... - - -@dataclass -class BaseObjectTypeFilterMixin(BaseFilter): - id: FilterLookup[ID] | None = strawberry_django.filter_field() diff --git a/netbox/core/graphql/filters.py b/netbox/core/graphql/filters.py index aa908cc655e..2e78b878b65 100644 --- a/netbox/core/graphql/filters.py +++ b/netbox/core/graphql/filters.py @@ -8,8 +8,7 @@ from strawberry_django import BaseFilterLookup, DatetimeFilterLookup, FilterLookup from core import models -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin -from netbox.graphql.filters import PrimaryModelFilter +from netbox.graphql.filters import BaseModelFilter, PrimaryModelFilter from .enums import * if TYPE_CHECKING: @@ -25,7 +24,7 @@ @strawberry_django.filter_type(models.DataFile, lookups=True) -class DataFileFilter(BaseObjectTypeFilterMixin): +class DataFileFilter(BaseModelFilter): created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() source: Annotated['DataSourceFilter', strawberry.lazy('core.graphql.filters')] | None = ( @@ -59,7 +58,7 @@ class DataSourceFilter(PrimaryModelFilter): @strawberry_django.filter_type(models.ObjectChange, lookups=True) -class ObjectChangeFilter(BaseObjectTypeFilterMixin): +class ObjectChangeFilter(BaseModelFilter): time: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field() user_name: FilterLookup[str] | None = strawberry_django.filter_field() @@ -86,6 +85,6 @@ class ObjectChangeFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter_type(DjangoContentType, lookups=True) -class ContentTypeFilter(BaseObjectTypeFilterMixin): +class ContentTypeFilter(BaseModelFilter): app_label: FilterLookup[str] | None = strawberry_django.filter_field() model: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/dcim/graphql/filter_mixins.py b/netbox/dcim/graphql/filter_mixins.py index a0a5355501c..2f5f6016c49 100644 --- a/netbox/dcim/graphql/filter_mixins.py +++ b/netbox/dcim/graphql/filter_mixins.py @@ -6,7 +6,6 @@ from strawberry import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseFilter from core.graphql.filters import ContentTypeFilter from netbox.graphql.filter_mixins import WeightFilterMixin from netbox.graphql.filters import ChangeLoggedModelFilter, NetBoxModelFilter, PrimaryModelFilter @@ -32,7 +31,7 @@ @dataclass -class ScopedFilterMixin(BaseFilter): +class ScopedFilterMixin: scope_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -58,7 +57,7 @@ class ModularComponentModelFilter(ComponentModelFilter): @dataclass -class CabledObjectModelFilterMixin(BaseFilter): +class CabledObjectModelFilterMixin: cable: Annotated['CableFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() cable_id: ID | None = strawberry_django.filter_field() cable_end: ( @@ -86,7 +85,7 @@ class ModularComponentTemplateFilter(ComponentTemplateFilter): @dataclass -class RenderConfigFilterMixin(BaseFilter): +class RenderConfigFilterMixin: config_template: Annotated['ConfigTemplateFilter', strawberry.lazy('extras.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -94,7 +93,7 @@ class RenderConfigFilterMixin(BaseFilter): @dataclass -class InterfaceBaseFilterMixin(BaseFilter): +class InterfaceBaseFilterMixin: enabled: FilterLookup[bool] | None = strawberry_django.filter_field() mtu: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() diff --git a/netbox/extras/graphql/filter_mixins.py b/netbox/extras/graphql/filter_mixins.py index 75a4c548c73..f990300ad8a 100644 --- a/netbox/extras/graphql/filter_mixins.py +++ b/netbox/extras/graphql/filter_mixins.py @@ -5,8 +5,6 @@ import strawberry_django from strawberry_django import FilterLookup -from core.graphql.filter_mixins import BaseFilter - if TYPE_CHECKING: from netbox.graphql.filter_lookups import JSONFilter from .filters import * @@ -21,32 +19,32 @@ @dataclass -class CustomFieldsFilterMixin(BaseFilter): +class CustomFieldsFilterMixin: custom_field_data: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @dataclass -class JournalEntriesFilterMixin(BaseFilter): +class JournalEntriesFilterMixin: journal_entries: Annotated['JournalEntryFilter', strawberry.lazy('extras.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class TagsFilterMixin(BaseFilter): +class TagsFilterMixin: tags: Annotated['TagFilter', strawberry.lazy('extras.graphql.filters')] | None = strawberry_django.filter_field() @dataclass -class ConfigContextFilterMixin(BaseFilter): +class ConfigContextFilterMixin: local_context_data: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) @dataclass -class TagBaseFilter(BaseFilter): +class TagBaseFilter: name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/extras/graphql/filters.py b/netbox/extras/graphql/filters.py index a21319b29d8..01080c290f0 100644 --- a/netbox/extras/graphql/filters.py +++ b/netbox/extras/graphql/filters.py @@ -5,7 +5,6 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from extras import models from extras.graphql.filter_mixins import TagBaseFilter, CustomFieldsFilterMixin, TagsFilterMixin from netbox.graphql.filter_mixins import SyncedDataFilterMixin @@ -43,7 +42,7 @@ @strawberry_django.filter_type(models.ConfigContext, lookups=True) -class ConfigContextFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLoggedModelFilter): +class ConfigContextFilter(SyncedDataFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() @@ -107,7 +106,7 @@ class ConfigContextProfileFilter(SyncedDataFilterMixin, PrimaryModelFilter): @strawberry_django.filter_type(models.ConfigTemplate, lookups=True) -class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLoggedModelFilter): +class ConfigTemplateFilter(SyncedDataFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() template_code: FilterLookup[str] | None = strawberry_django.filter_field() @@ -121,7 +120,7 @@ class ConfigTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, Cha @strawberry_django.filter_type(models.CustomField, lookups=True) -class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class CustomFieldFilter(ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['CustomFieldTypeEnum', strawberry.lazy('extras.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -180,7 +179,7 @@ class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): @strawberry_django.filter_type(models.CustomFieldChoiceSet, lookups=True) -class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class CustomFieldChoiceSetFilter(ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() base_choices: ( @@ -195,7 +194,7 @@ class CustomFieldChoiceSetFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFil @strawberry_django.filter_type(models.CustomLink, lookups=True) -class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class CustomLinkFilter(ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() enabled: FilterLookup[bool] | None = strawberry_django.filter_field() link_text: FilterLookup[str] | None = strawberry_django.filter_field() @@ -213,7 +212,7 @@ class CustomLinkFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): @strawberry_django.filter_type(models.ExportTemplate, lookups=True) -class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, ChangeLoggedModelFilter): +class ExportTemplateFilter(SyncedDataFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() template_code: FilterLookup[str] | None = strawberry_django.filter_field() @@ -227,7 +226,7 @@ class ExportTemplateFilter(BaseObjectTypeFilterMixin, SyncedDataFilterMixin, Cha @strawberry_django.filter_type(models.ImageAttachment, lookups=True) -class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class ImageAttachmentFilter(ChangeLoggedModelFilter): object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -242,7 +241,7 @@ class ImageAttachmentFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): @strawberry_django.filter_type(models.JournalEntry, lookups=True) -class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): +class JournalEntryFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): assigned_object_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -258,7 +257,7 @@ class JournalEntryFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, Tag @strawberry_django.filter_type(models.NotificationGroup, lookups=True) -class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class NotificationGroupFilter(ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() groups: Annotated['GroupFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field() @@ -266,7 +265,7 @@ class NotificationGroupFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter @strawberry_django.filter_type(models.SavedFilter, lookups=True) -class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class SavedFilterFilter(ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() @@ -283,7 +282,7 @@ class SavedFilterFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): @strawberry_django.filter_type(models.TableConfig, lookups=True) -class TableConfigFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class TableConfigFilter(ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() user: Annotated['UserFilter', strawberry.lazy('users.graphql.filters')] | None = strawberry_django.filter_field() @@ -296,7 +295,7 @@ class TableConfigFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): @strawberry_django.filter_type(models.Tag, lookups=True) -class TagFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter, TagBaseFilter): +class TagFilter(ChangeLoggedModelFilter, TagBaseFilter): color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -304,7 +303,7 @@ class TagFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter, TagBaseFilte @strawberry_django.filter_type(models.Webhook, lookups=True) -class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): +class WebhookFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() payload_url: FilterLookup[str] | None = strawberry_django.filter_field() @@ -325,7 +324,7 @@ class WebhookFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilt @strawberry_django.filter_type(models.EventRule, lookups=True) -class EventRuleFilter(BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): +class EventRuleFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() event_types: Annotated['StringArrayLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( diff --git a/netbox/ipam/graphql/filter_mixins.py b/netbox/ipam/graphql/filter_mixins.py index 07589cdf5d8..817f7210019 100644 --- a/netbox/ipam/graphql/filter_mixins.py +++ b/netbox/ipam/graphql/filter_mixins.py @@ -4,8 +4,6 @@ import strawberry import strawberry_django -from core.graphql.filter_mixins import BaseFilter - if TYPE_CHECKING: from netbox.graphql.filter_lookups import IntegerLookup from .enums import * @@ -16,7 +14,7 @@ @dataclass -class ServiceBaseFilterMixin(BaseFilter): +class ServiceBaseFilterMixin: protocol: Annotated['ServiceProtocolEnum', strawberry.lazy('ipam.graphql.enums')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/ipam/graphql/filters.py b/netbox/ipam/graphql/filters.py index b41a0dab8e3..7d0e22558f5 100644 --- a/netbox/ipam/graphql/filters.py +++ b/netbox/ipam/graphql/filters.py @@ -9,7 +9,6 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup, DateFilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from dcim.graphql.filter_mixins import ScopedFilterMixin from dcim.models import Device from ipam import models @@ -131,7 +130,7 @@ class FHRPGroupFilter(PrimaryModelFilter): @strawberry_django.filter_type(models.FHRPGroupAssignment, lookups=True) -class FHRPGroupAssignmentFilter(BaseObjectTypeFilterMixin, ChangeLoggedModelFilter): +class FHRPGroupAssignmentFilter(ChangeLoggedModelFilter): interface_type: Annotated['ContentTypeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/netbox/graphql/filter_mixins.py b/netbox/netbox/graphql/filter_mixins.py index 19340e63ff9..3bb81890765 100644 --- a/netbox/netbox/graphql/filter_mixins.py +++ b/netbox/netbox/graphql/filter_mixins.py @@ -6,8 +6,6 @@ import strawberry_django from strawberry_django import BaseFilterLookup, FilterLookup, DatetimeFilterLookup -from core.graphql.filter_mixins import BaseFilter - __all__ = ( 'DistanceFilterMixin', 'ImageAttachmentFilterMixin', @@ -25,14 +23,14 @@ @dataclass -class ImageAttachmentFilterMixin(BaseFilter): +class ImageAttachmentFilterMixin: images: Annotated['ImageAttachmentFilter', strawberry.lazy('extras.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class WeightFilterMixin(BaseFilter): +class WeightFilterMixin: weight: FilterLookup[float] | None = strawberry_django.filter_field() weight_unit: BaseFilterLookup[Annotated['WeightUnitEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() @@ -40,7 +38,7 @@ class WeightFilterMixin(BaseFilter): @dataclass -class SyncedDataFilterMixin(BaseFilter): +class SyncedDataFilterMixin: data_source: Annotated['DataSourceFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -55,7 +53,7 @@ class SyncedDataFilterMixin(BaseFilter): @dataclass -class DistanceFilterMixin(BaseFilter): +class DistanceFilterMixin: distance: FilterLookup[float] | None = strawberry_django.filter_field() distance_unit: BaseFilterLookup[Annotated['DistanceUnitEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() diff --git a/netbox/netbox/graphql/filters.py b/netbox/netbox/graphql/filters.py index 4b48b56a31e..dc8b40d2b8e 100644 --- a/netbox/netbox/graphql/filters.py +++ b/netbox/netbox/graphql/filters.py @@ -7,13 +7,13 @@ from strawberry import ID from strawberry_django import FilterLookup, DatetimeFilterLookup -from core.graphql.filter_mixins import BaseFilter from extras.graphql.filter_mixins import CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin if TYPE_CHECKING: from .filters import * __all__ = ( + 'BaseModelFilter', 'ChangeLoggedModelFilter', 'NestedGroupModelFilter', 'NetBoxModelFilter', @@ -22,9 +22,12 @@ ) -@dataclass -class ChangeLoggedModelFilter(BaseFilter): +class BaseModelFilter: id: FilterLookup[ID] | None = strawberry_django.filter_field() + + +@dataclass +class ChangeLoggedModelFilter(BaseModelFilter): # TODO: "changelog" is not a valid field name; needs to be updated for ObjectChange changelog: Annotated['ObjectChangeFilter', strawberry.lazy('core.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -34,11 +37,10 @@ class ChangeLoggedModelFilter(BaseFilter): class NetBoxModelFilter( - ChangeLoggedModelFilter, CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin, - BaseFilter, + ChangeLoggedModelFilter, ): pass diff --git a/netbox/tenancy/graphql/filter_mixins.py b/netbox/tenancy/graphql/filter_mixins.py index 698b031e1cb..1e924ac2de8 100644 --- a/netbox/tenancy/graphql/filter_mixins.py +++ b/netbox/tenancy/graphql/filter_mixins.py @@ -5,8 +5,6 @@ import strawberry_django from strawberry import ID -from core.graphql.filter_mixins import BaseFilter - if TYPE_CHECKING: from netbox.graphql.filter_lookups import TreeNodeFilter from .filters import ContactAssignmentFilter, TenantFilter, TenantGroupFilter @@ -18,14 +16,14 @@ @dataclass -class ContactFilterMixin(BaseFilter): +class ContactFilterMixin: contacts: Annotated['ContactAssignmentFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( strawberry_django.filter_field() ) @dataclass -class TenancyFilterMixin(BaseFilter): +class TenancyFilterMixin: tenant: Annotated['TenantFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/users/graphql/filters.py b/netbox/users/graphql/filters.py index 52a768b8541..63728c46b05 100644 --- a/netbox/users/graphql/filters.py +++ b/netbox/users/graphql/filters.py @@ -5,7 +5,7 @@ import strawberry_django from strawberry_django import DatetimeFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin +from netbox.graphql.filters import BaseModelFilter from users import models __all__ = ( @@ -17,13 +17,13 @@ @strawberry_django.filter_type(models.Group, lookups=True) -class GroupFilter(BaseObjectTypeFilterMixin): +class GroupFilter(BaseModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() @strawberry_django.filter_type(models.User, lookups=True) -class UserFilter(BaseObjectTypeFilterMixin): +class UserFilter(BaseModelFilter): username: FilterLookup[str] | None = strawberry_django.filter_field() first_name: FilterLookup[str] | None = strawberry_django.filter_field() last_name: FilterLookup[str] | None = strawberry_django.filter_field() @@ -36,7 +36,7 @@ class UserFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter_type(models.Owner, lookups=True) -class OwnerFilter(BaseObjectTypeFilterMixin): +class OwnerFilter(BaseModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() group: Annotated['OwnerGroupFilter', strawberry.lazy('users.graphql.filters')] | None = ( @@ -49,6 +49,6 @@ class OwnerFilter(BaseObjectTypeFilterMixin): @strawberry_django.filter_type(models.OwnerGroup, lookups=True) -class OwnerGroupFilter(BaseObjectTypeFilterMixin): +class OwnerGroupFilter(BaseModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() description: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/vpn/graphql/filters.py b/netbox/vpn/graphql/filters.py index 83963b66626..bd5471ace00 100644 --- a/netbox/vpn/graphql/filters.py +++ b/netbox/vpn/graphql/filters.py @@ -5,7 +5,6 @@ from strawberry.scalars import ID from strawberry_django import BaseFilterLookup, FilterLookup -from core.graphql.filter_mixins import BaseObjectTypeFilterMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin from netbox.graphql.filters import ( ChangeLoggedModelFilter, NetBoxModelFilter, OrganizationalModelFilter, PrimaryModelFilter, @@ -39,9 +38,7 @@ class TunnelGroupFilter(OrganizationalModelFilter): @strawberry_django.filter_type(models.TunnelTermination, lookups=True) -class TunnelTerminationFilter( - BaseObjectTypeFilterMixin, CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter -): +class TunnelTerminationFilter(CustomFieldsFilterMixin, TagsFilterMixin, ChangeLoggedModelFilter): tunnel: Annotated['TunnelFilter', strawberry.lazy('vpn.graphql.filters')] | None = strawberry_django.filter_field() tunnel_id: ID | None = strawberry_django.filter_field() role: BaseFilterLookup[Annotated['TunnelTerminationRoleEnum', strawberry.lazy('vpn.graphql.enums')]] | None = ( diff --git a/netbox/wireless/graphql/filter_mixins.py b/netbox/wireless/graphql/filter_mixins.py index 966255aff29..d795209cfa5 100644 --- a/netbox/wireless/graphql/filter_mixins.py +++ b/netbox/wireless/graphql/filter_mixins.py @@ -5,8 +5,6 @@ import strawberry_django from strawberry_django import FilterLookup -from core.graphql.filter_mixins import BaseFilter - if TYPE_CHECKING: from .enums import * @@ -16,7 +14,7 @@ @dataclass -class WirelessAuthenticationBaseFilterMixin(BaseFilter): +class WirelessAuthenticationBaseFilterMixin: auth_type: Annotated['WirelessAuthTypeEnum', strawberry.lazy('wireless.graphql.enums')] | None = ( strawberry_django.filter_field() ) From bfab461e43272271932fb468610ce7ca383eca03 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 5 Dec 2025 15:47:20 -0500 Subject: [PATCH 3/6] Move changelogging filters to ChangeLoggingMixin --- netbox/core/graphql/filter_mixins.py | 24 ++++++++++++++++++++++++ netbox/netbox/graphql/filters.py | 21 ++++++++------------- 2 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 netbox/core/graphql/filter_mixins.py diff --git a/netbox/core/graphql/filter_mixins.py b/netbox/core/graphql/filter_mixins.py new file mode 100644 index 00000000000..7383f6c4ef3 --- /dev/null +++ b/netbox/core/graphql/filter_mixins.py @@ -0,0 +1,24 @@ +from dataclasses import dataclass +from datetime import datetime +from typing import Annotated, TYPE_CHECKING + +import strawberry +import strawberry_django +from strawberry_django import DatetimeFilterLookup + +if TYPE_CHECKING: + from .filters import * + +__all__ = ( + 'ChangeLoggingMixin', +) + + +@dataclass +class ChangeLoggingMixin: + # TODO: "changelog" is not a valid field name; needs to be updated for ObjectChange + changelog: Annotated['ObjectChangeFilter', strawberry.lazy('core.graphql.filters')] | None = ( + strawberry_django.filter_field() + ) + created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() + last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() diff --git a/netbox/netbox/graphql/filters.py b/netbox/netbox/graphql/filters.py index dc8b40d2b8e..ff0aa85e92f 100644 --- a/netbox/netbox/graphql/filters.py +++ b/netbox/netbox/graphql/filters.py @@ -1,12 +1,11 @@ from dataclasses import dataclass -from datetime import datetime -from typing import Annotated, TYPE_CHECKING +from typing import TYPE_CHECKING -import strawberry import strawberry_django from strawberry import ID -from strawberry_django import FilterLookup, DatetimeFilterLookup +from strawberry_django import FilterLookup +from core.graphql.filter_mixins import ChangeLoggingMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin if TYPE_CHECKING: @@ -22,25 +21,21 @@ ) +@dataclass class BaseModelFilter: id: FilterLookup[ID] | None = strawberry_django.filter_field() -@dataclass -class ChangeLoggedModelFilter(BaseModelFilter): - # TODO: "changelog" is not a valid field name; needs to be updated for ObjectChange - changelog: Annotated['ObjectChangeFilter', strawberry.lazy('core.graphql.filters')] | None = ( - strawberry_django.filter_field() - ) - created: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() - last_updated: DatetimeFilterLookup[datetime] | None = strawberry_django.filter_field() +class ChangeLoggedModelFilter(ChangeLoggingMixin, BaseModelFilter): + pass class NetBoxModelFilter( CustomFieldsFilterMixin, JournalEntriesFilterMixin, TagsFilterMixin, - ChangeLoggedModelFilter, + ChangeLoggingMixin, + BaseModelFilter ): pass From 69057dd02c92a2ec5f29351a0e33f9ccb461c133 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 5 Dec 2025 16:31:31 -0500 Subject: [PATCH 4/6] Refactor filter mixins --- netbox/circuits/graphql/filter_mixins.py | 11 +-- netbox/circuits/graphql/filters.py | 6 +- netbox/dcim/graphql/filter_mixins.py | 22 +++--- netbox/dcim/graphql/filters.py | 70 +++++++++++-------- netbox/extras/graphql/filter_mixins.py | 8 --- netbox/extras/graphql/filters.py | 6 +- netbox/ipam/graphql/filter_mixins.py | 4 +- netbox/ipam/graphql/filters.py | 6 +- .../virtualization/graphql/filter_mixins.py | 8 +-- netbox/virtualization/graphql/filters.py | 8 +-- netbox/wireless/graphql/filter_mixins.py | 4 +- netbox/wireless/graphql/filters.py | 6 +- 12 files changed, 82 insertions(+), 77 deletions(-) diff --git a/netbox/circuits/graphql/filter_mixins.py b/netbox/circuits/graphql/filter_mixins.py index 0781288cc98..f7795f10adc 100644 --- a/netbox/circuits/graphql/filter_mixins.py +++ b/netbox/circuits/graphql/filter_mixins.py @@ -3,17 +3,18 @@ import strawberry import strawberry_django - -from netbox.graphql.filters import OrganizationalModelFilter +from strawberry_django import BaseFilterLookup if TYPE_CHECKING: from netbox.graphql.enums import ColorEnum __all__ = ( - 'BaseCircuitTypeFilter', + 'CircuitTypeFilterMixin', ) @dataclass -class BaseCircuitTypeFilter(OrganizationalModelFilter): - color: Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')] | None = strawberry_django.filter_field() +class CircuitTypeFilterMixin: + color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( + strawberry_django.filter_field() + ) diff --git a/netbox/circuits/graphql/filters.py b/netbox/circuits/graphql/filters.py index 25e267a5f7d..160dd9c2b0d 100644 --- a/netbox/circuits/graphql/filters.py +++ b/netbox/circuits/graphql/filters.py @@ -7,12 +7,12 @@ from strawberry_django import BaseFilterLookup, FilterLookup, DateFilterLookup from circuits import models +from circuits.graphql.filter_mixins import CircuitTypeFilterMixin from dcim.graphql.filter_mixins import CabledObjectModelFilterMixin from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin from netbox.graphql.filter_mixins import DistanceFilterMixin, ImageAttachmentFilterMixin from netbox.graphql.filters import ChangeLoggedModelFilter, OrganizationalModelFilter, PrimaryModelFilter from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin -from .filter_mixins import BaseCircuitTypeFilter if TYPE_CHECKING: from core.graphql.filters import ContentTypeFilter @@ -118,7 +118,7 @@ class CircuitFilter( @strawberry_django.filter_type(models.CircuitType, lookups=True) -class CircuitTypeFilter(BaseCircuitTypeFilter): +class CircuitTypeFilter(CircuitTypeFilterMixin, OrganizationalModelFilter): pass @@ -173,7 +173,7 @@ class ProviderNetworkFilter(PrimaryModelFilter): @strawberry_django.filter_type(models.VirtualCircuitType, lookups=True) -class VirtualCircuitTypeFilter(BaseCircuitTypeFilter): +class VirtualCircuitTypeFilter(CircuitTypeFilterMixin, OrganizationalModelFilter): pass diff --git a/netbox/dcim/graphql/filter_mixins.py b/netbox/dcim/graphql/filter_mixins.py index 2f5f6016c49..e0f6bbc1dc7 100644 --- a/netbox/dcim/graphql/filter_mixins.py +++ b/netbox/dcim/graphql/filter_mixins.py @@ -7,8 +7,6 @@ from strawberry_django import BaseFilterLookup, FilterLookup from core.graphql.filters import ContentTypeFilter -from netbox.graphql.filter_mixins import WeightFilterMixin -from netbox.graphql.filters import ChangeLoggedModelFilter, NetBoxModelFilter, PrimaryModelFilter from .enums import * if TYPE_CHECKING: @@ -19,12 +17,12 @@ __all__ = ( 'CabledObjectModelFilterMixin', - 'ComponentModelFilter', - 'ComponentTemplateFilter', + 'ComponentModelFilterMixin', + 'ComponentTemplateFilterMixin', 'InterfaceBaseFilterMixin', - 'ModularComponentModelFilter', - 'ModularComponentTemplateFilter', - 'RackBaseFilter', + 'ModularComponentModelFilterMixin', + 'ModularComponentTemplateFilterMixin', + 'RackFilterMixin', 'RenderConfigFilterMixin', 'ScopedFilterMixin', ) @@ -39,7 +37,7 @@ class ScopedFilterMixin: @dataclass -class ComponentModelFilter(NetBoxModelFilter): +class ComponentModelFilterMixin: device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() device_id: ID | None = strawberry_django.filter_field() name: FilterLookup[str] | None = strawberry_django.filter_field() @@ -48,7 +46,7 @@ class ComponentModelFilter(NetBoxModelFilter): @dataclass -class ModularComponentModelFilter(ComponentModelFilter): +class ModularComponentModelFilterMixin(ComponentModelFilterMixin): module: Annotated['ModuleFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() module_id: ID | None = strawberry_django.filter_field() inventory_items: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( @@ -67,7 +65,7 @@ class CabledObjectModelFilterMixin: @dataclass -class ComponentTemplateFilter(ChangeLoggedModelFilter): +class ComponentTemplateFilterMixin: device_type: Annotated['DeviceTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -78,7 +76,7 @@ class ComponentTemplateFilter(ChangeLoggedModelFilter): @dataclass -class ModularComponentTemplateFilter(ComponentTemplateFilter): +class ModularComponentTemplateFilterMixin(ComponentTemplateFilterMixin): module_type: Annotated['ModuleTypeFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -124,7 +122,7 @@ class InterfaceBaseFilterMixin: @dataclass -class RackBaseFilter(WeightFilterMixin, PrimaryModelFilter): +class RackFilterMixin: width: BaseFilterLookup[Annotated['RackWidthEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/dcim/graphql/filters.py b/netbox/dcim/graphql/filters.py index c54673fa872..49fd9f817ff 100644 --- a/netbox/dcim/graphql/filters.py +++ b/netbox/dcim/graphql/filters.py @@ -9,22 +9,21 @@ from dcim import models from dcim.constants import * from dcim.graphql.enums import InterfaceKindEnum +from dcim.graphql.filter_mixins import ( + ComponentModelFilterMixin, ComponentTemplateFilterMixin, ModularComponentModelFilterMixin, + ModularComponentTemplateFilterMixin, RackFilterMixin, +) from extras.graphql.filter_mixins import ConfigContextFilterMixin from netbox.graphql.filter_mixins import ImageAttachmentFilterMixin, WeightFilterMixin from netbox.graphql.filters import ( - ChangeLoggedModelFilter, NestedGroupModelFilter, OrganizationalModelFilter, PrimaryModelFilter, + ChangeLoggedModelFilter, NestedGroupModelFilter, OrganizationalModelFilter, PrimaryModelFilter, NetBoxModelFilter, ) from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin from virtualization.models import VMInterface from .filter_mixins import ( CabledObjectModelFilterMixin, - ComponentModelFilter, - ComponentTemplateFilter, InterfaceBaseFilterMixin, - ModularComponentModelFilter, - ModularComponentTemplateFilter, - RackBaseFilter, RenderConfigFilterMixin, ) @@ -128,7 +127,7 @@ class CableTerminationFilter(ChangeLoggedModelFilter): @strawberry_django.filter_type(models.ConsolePort, lookups=True) -class ConsolePortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): +class ConsolePortFilter(ModularComponentTemplateFilterMixin, CabledObjectModelFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -138,14 +137,18 @@ class ConsolePortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixi @strawberry_django.filter_type(models.ConsolePortTemplate, lookups=True) -class ConsolePortTemplateFilter(ModularComponentTemplateFilter): +class ConsolePortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @strawberry_django.filter_type(models.ConsoleServerPort, lookups=True) -class ConsoleServerPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): +class ConsoleServerPortFilter( + ModularComponentTemplateFilterMixin, + CabledObjectModelFilterMixin, + ChangeLoggedModelFilter +): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -155,7 +158,7 @@ class ConsoleServerPortFilter(ModularComponentModelFilter, CabledObjectModelFilt @strawberry_django.filter_type(models.ConsoleServerPortTemplate, lookups=True) -class ConsoleServerPortTemplateFilter(ModularComponentTemplateFilter): +class ConsoleServerPortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -281,7 +284,7 @@ class DeviceFilter( @strawberry_django.filter_type(models.DeviceBay, lookups=True) -class DeviceBayFilter(ComponentModelFilter): +class DeviceBayFilter(ComponentModelFilterMixin, NetBoxModelFilter): installed_device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -289,12 +292,12 @@ class DeviceBayFilter(ComponentModelFilter): @strawberry_django.filter_type(models.DeviceBayTemplate, lookups=True) -class DeviceBayTemplateFilter(ComponentTemplateFilter): +class DeviceBayTemplateFilter(ComponentTemplateFilterMixin, ChangeLoggedModelFilter): pass @strawberry_django.filter_type(models.InventoryItemTemplate, lookups=True) -class InventoryItemTemplateFilter(ComponentTemplateFilter): +class InventoryItemTemplateFilter(ComponentTemplateFilterMixin, ChangeLoggedModelFilter): parent: Annotated['InventoryItemTemplateFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -398,7 +401,7 @@ class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilter, WeightFil @strawberry_django.filter_type(models.FrontPort, lookups=True) -class FrontPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): +class FrontPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -415,7 +418,7 @@ class FrontPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin) @strawberry_django.filter_type(models.FrontPortTemplate, lookups=True) -class FrontPortTemplateFilter(ModularComponentTemplateFilter): +class FrontPortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -459,7 +462,12 @@ def primary(self, value: bool, prefix) -> Q: @strawberry_django.filter_type(models.Interface, lookups=True) -class InterfaceFilter(ModularComponentModelFilter, InterfaceBaseFilterMixin, CabledObjectModelFilterMixin): +class InterfaceFilter( + ModularComponentModelFilterMixin, + InterfaceBaseFilterMixin, + CabledObjectModelFilterMixin, + NetBoxModelFilter +): vcdcs: Annotated['VirtualDeviceContextFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -549,7 +557,7 @@ def kind( @strawberry_django.filter_type(models.InterfaceTemplate, lookups=True) -class InterfaceTemplateFilter(ModularComponentTemplateFilter): +class InterfaceTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['InterfaceTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -571,7 +579,7 @@ class InterfaceTemplateFilter(ModularComponentTemplateFilter): @strawberry_django.filter_type(models.InventoryItem, lookups=True) -class InventoryItemFilter(ComponentModelFilter): +class InventoryItemFilter(ComponentModelFilterMixin, NetBoxModelFilter): parent: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -675,7 +683,7 @@ class ModuleFilter(PrimaryModelFilter, ConfigContextFilterMixin): @strawberry_django.filter_type(models.ModuleBay, lookups=True) -class ModuleBayFilter(ModularComponentModelFilter): +class ModuleBayFilter(ModularComponentModelFilterMixin, NetBoxModelFilter): parent: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -684,7 +692,7 @@ class ModuleBayFilter(ModularComponentModelFilter): @strawberry_django.filter_type(models.ModuleBayTemplate, lookups=True) -class ModuleBayTemplateFilter(ModularComponentTemplateFilter): +class ModuleBayTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): position: FilterLookup[str] | None = strawberry_django.filter_field() @@ -792,7 +800,7 @@ class PowerFeedFilter(CabledObjectModelFilterMixin, TenancyFilterMixin, PrimaryM @strawberry_django.filter_type(models.PowerOutlet, lookups=True) -class PowerOutletFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): +class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -812,7 +820,7 @@ class PowerOutletFilter(ModularComponentModelFilter, CabledObjectModelFilterMixi @strawberry_django.filter_type(models.PowerOutletTemplate, lookups=True) -class PowerOutletTemplateFilter(ModularComponentModelFilter): +class PowerOutletTemplateFilter(ModularComponentModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -839,7 +847,7 @@ class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryMo @strawberry_django.filter_type(models.PowerPort, lookups=True) -class PowerPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): +class PowerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -852,7 +860,7 @@ class PowerPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin) @strawberry_django.filter_type(models.PowerPortTemplate, lookups=True) -class PowerPortTemplateFilter(ModularComponentTemplateFilter): +class PowerPortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -865,7 +873,7 @@ class PowerPortTemplateFilter(ModularComponentTemplateFilter): @strawberry_django.filter_type(models.RackType, lookups=True) -class RackTypeFilter(RackBaseFilter): +class RackTypeFilter(RackFilterMixin, WeightFilterMixin, PrimaryModelFilter): form_factor: BaseFilterLookup[Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -880,7 +888,13 @@ class RackTypeFilter(RackBaseFilter): @strawberry_django.filter_type(models.Rack, lookups=True) -class RackFilter(ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, RackBaseFilter): +class RackFilter( + ContactFilterMixin, + ImageAttachmentFilterMixin, + TenancyFilterMixin, + RackFilterMixin, + PrimaryModelFilter +): form_factor: BaseFilterLookup[Annotated['RackFormFactorEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -936,7 +950,7 @@ class RackRoleFilter(OrganizationalModelFilter): @strawberry_django.filter_type(models.RearPort, lookups=True) -class RearPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): +class RearPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -949,7 +963,7 @@ class RearPortFilter(ModularComponentModelFilter, CabledObjectModelFilterMixin): @strawberry_django.filter_type(models.RearPortTemplate, lookups=True) -class RearPortTemplateFilter(ModularComponentTemplateFilter): +class RearPortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/extras/graphql/filter_mixins.py b/netbox/extras/graphql/filter_mixins.py index f990300ad8a..4b5636c0eaa 100644 --- a/netbox/extras/graphql/filter_mixins.py +++ b/netbox/extras/graphql/filter_mixins.py @@ -3,7 +3,6 @@ import strawberry import strawberry_django -from strawberry_django import FilterLookup if TYPE_CHECKING: from netbox.graphql.filter_lookups import JSONFilter @@ -14,7 +13,6 @@ 'JournalEntriesFilterMixin', 'TagsFilterMixin', 'ConfigContextFilterMixin', - 'TagBaseFilter', ) @@ -42,9 +40,3 @@ class ConfigContextFilterMixin: local_context_data: Annotated['JSONFilter', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) - - -@dataclass -class TagBaseFilter: - name: FilterLookup[str] | None = strawberry_django.filter_field() - slug: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/extras/graphql/filters.py b/netbox/extras/graphql/filters.py index 01080c290f0..12b773f03aa 100644 --- a/netbox/extras/graphql/filters.py +++ b/netbox/extras/graphql/filters.py @@ -6,7 +6,7 @@ from strawberry_django import BaseFilterLookup, FilterLookup from extras import models -from extras.graphql.filter_mixins import TagBaseFilter, CustomFieldsFilterMixin, TagsFilterMixin +from extras.graphql.filter_mixins import CustomFieldsFilterMixin, TagsFilterMixin from netbox.graphql.filter_mixins import SyncedDataFilterMixin from netbox.graphql.filters import ChangeLoggedModelFilter, PrimaryModelFilter @@ -295,7 +295,9 @@ class TableConfigFilter(ChangeLoggedModelFilter): @strawberry_django.filter_type(models.Tag, lookups=True) -class TagFilter(ChangeLoggedModelFilter, TagBaseFilter): +class TagFilter(ChangeLoggedModelFilter): + name: FilterLookup[str] | None = strawberry_django.filter_field() + slug: FilterLookup[str] | None = strawberry_django.filter_field() color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/ipam/graphql/filter_mixins.py b/netbox/ipam/graphql/filter_mixins.py index 817f7210019..36666f781f0 100644 --- a/netbox/ipam/graphql/filter_mixins.py +++ b/netbox/ipam/graphql/filter_mixins.py @@ -9,12 +9,12 @@ from .enums import * __all__ = ( - 'ServiceBaseFilterMixin', + 'ServiceFilterMixin', ) @dataclass -class ServiceBaseFilterMixin: +class ServiceFilterMixin: protocol: Annotated['ServiceProtocolEnum', strawberry.lazy('ipam.graphql.enums')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/ipam/graphql/filters.py b/netbox/ipam/graphql/filters.py index 7d0e22558f5..c1cca193e4a 100644 --- a/netbox/ipam/graphql/filters.py +++ b/netbox/ipam/graphql/filters.py @@ -12,7 +12,7 @@ from dcim.graphql.filter_mixins import ScopedFilterMixin from dcim.models import Device from ipam import models -from ipam.graphql.filter_mixins import ServiceBaseFilterMixin +from ipam.graphql.filter_mixins import ServiceFilterMixin from netbox.graphql.filters import ( ChangeLoggedModelFilter, NetBoxModelFilter, OrganizationalModelFilter, PrimaryModelFilter, ) @@ -340,7 +340,7 @@ class RouteTargetFilter(TenancyFilterMixin, PrimaryModelFilter): @strawberry_django.filter_type(models.Service, lookups=True) -class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilter): +class ServiceFilter(ContactFilterMixin, ServiceFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() @@ -352,7 +352,7 @@ class ServiceFilter(ContactFilterMixin, ServiceBaseFilterMixin, PrimaryModelFilt @strawberry_django.filter_type(models.ServiceTemplate, lookups=True) -class ServiceTemplateFilter(ServiceBaseFilterMixin, PrimaryModelFilter): +class ServiceTemplateFilter(ServiceFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() diff --git a/netbox/virtualization/graphql/filter_mixins.py b/netbox/virtualization/graphql/filter_mixins.py index 134db450644..c387f4c4eea 100644 --- a/netbox/virtualization/graphql/filter_mixins.py +++ b/netbox/virtualization/graphql/filter_mixins.py @@ -3,21 +3,19 @@ import strawberry import strawberry_django -from strawberry import ID +from strawberry.scalars import ID from strawberry_django import FilterLookup -from netbox.graphql.filters import NetBoxModelFilter - if TYPE_CHECKING: from .filters import VirtualMachineFilter __all__ = ( - 'VMComponentFilter', + 'VMComponentFilterMixin', ) @dataclass -class VMComponentFilter(NetBoxModelFilter): +class VMComponentFilterMixin: virtual_machine: Annotated['VirtualMachineFilter', strawberry.lazy('virtualization.graphql.filters')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/virtualization/graphql/filters.py b/netbox/virtualization/graphql/filters.py index c202ab30654..3bb71be6fb2 100644 --- a/netbox/virtualization/graphql/filters.py +++ b/netbox/virtualization/graphql/filters.py @@ -8,10 +8,10 @@ from dcim.graphql.filter_mixins import InterfaceBaseFilterMixin, RenderConfigFilterMixin, ScopedFilterMixin from extras.graphql.filter_mixins import ConfigContextFilterMixin from netbox.graphql.filter_mixins import ImageAttachmentFilterMixin -from netbox.graphql.filters import OrganizationalModelFilter, PrimaryModelFilter +from netbox.graphql.filters import NetBoxModelFilter, OrganizationalModelFilter, PrimaryModelFilter from tenancy.graphql.filter_mixins import ContactFilterMixin, TenancyFilterMixin from virtualization import models -from virtualization.graphql.filter_mixins import VMComponentFilter +from virtualization.graphql.filter_mixins import VMComponentFilterMixin if TYPE_CHECKING: from .enums import * @@ -135,7 +135,7 @@ class VirtualMachineFilter( @strawberry_django.filter_type(models.VMInterface, lookups=True) -class VMInterfaceFilter(VMComponentFilter, InterfaceBaseFilterMixin): +class VMInterfaceFilter(InterfaceBaseFilterMixin, VMComponentFilterMixin, NetBoxModelFilter): ip_addresses: Annotated['IPAddressFilter', strawberry.lazy('ipam.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -160,7 +160,7 @@ class VMInterfaceFilter(VMComponentFilter, InterfaceBaseFilterMixin): @strawberry_django.filter_type(models.VirtualDisk, lookups=True) -class VirtualDiskFilter(VMComponentFilter): +class VirtualDiskFilter(VMComponentFilterMixin, NetBoxModelFilter): size: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/wireless/graphql/filter_mixins.py b/netbox/wireless/graphql/filter_mixins.py index d795209cfa5..d5b85425ae1 100644 --- a/netbox/wireless/graphql/filter_mixins.py +++ b/netbox/wireless/graphql/filter_mixins.py @@ -9,12 +9,12 @@ from .enums import * __all__ = ( - 'WirelessAuthenticationBaseFilterMixin', + 'WirelessAuthenticationFilterMixin', ) @dataclass -class WirelessAuthenticationBaseFilterMixin: +class WirelessAuthenticationFilterMixin: auth_type: Annotated['WirelessAuthTypeEnum', strawberry.lazy('wireless.graphql.enums')] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/wireless/graphql/filters.py b/netbox/wireless/graphql/filters.py index d676ca89ce9..b1432ac8c43 100644 --- a/netbox/wireless/graphql/filters.py +++ b/netbox/wireless/graphql/filters.py @@ -10,7 +10,7 @@ from netbox.graphql.filters import PrimaryModelFilter, NestedGroupModelFilter from tenancy.graphql.filter_mixins import TenancyFilterMixin from wireless import models -from .filter_mixins import WirelessAuthenticationBaseFilterMixin +from .filter_mixins import WirelessAuthenticationFilterMixin if TYPE_CHECKING: from dcim.graphql.filters import InterfaceFilter @@ -31,7 +31,7 @@ class WirelessLANGroupFilter(NestedGroupModelFilter): @strawberry_django.filter_type(models.WirelessLAN, lookups=True) class WirelessLANFilter( - WirelessAuthenticationBaseFilterMixin, + WirelessAuthenticationFilterMixin, ScopedFilterMixin, TenancyFilterMixin, PrimaryModelFilter @@ -50,7 +50,7 @@ class WirelessLANFilter( @strawberry_django.filter_type(models.WirelessLink, lookups=True) class WirelessLinkFilter( - WirelessAuthenticationBaseFilterMixin, + WirelessAuthenticationFilterMixin, DistanceFilterMixin, TenancyFilterMixin, PrimaryModelFilter From 6c8dece4afb87dd6966c2e41b1262f86fe675046 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Fri, 5 Dec 2025 16:48:36 -0500 Subject: [PATCH 5/6] Misc cleanup --- netbox/dcim/graphql/filter_mixins.py | 4 ++-- netbox/dcim/graphql/filters.py | 31 ++++++++++++++-------------- netbox/ipam/graphql/filter_mixins.py | 3 ++- netbox/tenancy/graphql/filters.py | 2 +- 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/netbox/dcim/graphql/filter_mixins.py b/netbox/dcim/graphql/filter_mixins.py index e0f6bbc1dc7..c02c8994811 100644 --- a/netbox/dcim/graphql/filter_mixins.py +++ b/netbox/dcim/graphql/filter_mixins.py @@ -20,7 +20,7 @@ 'ComponentModelFilterMixin', 'ComponentTemplateFilterMixin', 'InterfaceBaseFilterMixin', - 'ModularComponentModelFilterMixin', + 'ModularComponentFilterMixin', 'ModularComponentTemplateFilterMixin', 'RackFilterMixin', 'RenderConfigFilterMixin', @@ -46,7 +46,7 @@ class ComponentModelFilterMixin: @dataclass -class ModularComponentModelFilterMixin(ComponentModelFilterMixin): +class ModularComponentFilterMixin(ComponentModelFilterMixin): module: Annotated['ModuleFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() module_id: ID | None = strawberry_django.filter_field() inventory_items: Annotated['InventoryItemFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( diff --git a/netbox/dcim/graphql/filters.py b/netbox/dcim/graphql/filters.py index 49fd9f817ff..ff2f89886ac 100644 --- a/netbox/dcim/graphql/filters.py +++ b/netbox/dcim/graphql/filters.py @@ -10,7 +10,7 @@ from dcim.constants import * from dcim.graphql.enums import InterfaceKindEnum from dcim.graphql.filter_mixins import ( - ComponentModelFilterMixin, ComponentTemplateFilterMixin, ModularComponentModelFilterMixin, + ComponentModelFilterMixin, ComponentTemplateFilterMixin, ModularComponentFilterMixin, ModularComponentTemplateFilterMixin, RackFilterMixin, ) from extras.graphql.filter_mixins import ConfigContextFilterMixin @@ -91,7 +91,7 @@ @strawberry_django.filter_type(models.Cable, lookups=True) -class CableFilter(PrimaryModelFilter, TenancyFilterMixin): +class CableFilter(TenancyFilterMixin, PrimaryModelFilter): type: BaseFilterLookup[Annotated['CableTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -127,7 +127,7 @@ class CableTerminationFilter(ChangeLoggedModelFilter): @strawberry_django.filter_type(models.ConsolePort, lookups=True) -class ConsolePortFilter(ModularComponentTemplateFilterMixin, CabledObjectModelFilterMixin, ChangeLoggedModelFilter): +class ConsolePortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -145,7 +145,7 @@ class ConsolePortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLogge @strawberry_django.filter_type(models.ConsoleServerPort, lookups=True) class ConsoleServerPortFilter( - ModularComponentTemplateFilterMixin, + ModularComponentFilterMixin, CabledObjectModelFilterMixin, ChangeLoggedModelFilter ): @@ -317,7 +317,7 @@ class InventoryItemTemplateFilter(ComponentTemplateFilterMixin, ChangeLoggedMode @strawberry_django.filter_type(models.DeviceRole, lookups=True) -class DeviceRoleFilter(OrganizationalModelFilter, RenderConfigFilterMixin): +class DeviceRoleFilter(RenderConfigFilterMixin, OrganizationalModelFilter): color: BaseFilterLookup[Annotated['ColorEnum', strawberry.lazy('netbox.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -325,7 +325,7 @@ class DeviceRoleFilter(OrganizationalModelFilter, RenderConfigFilterMixin): @strawberry_django.filter_type(models.DeviceType, lookups=True) -class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilter, WeightFilterMixin): +class DeviceTypeFilter(ImageAttachmentFilterMixin, WeightFilterMixin, PrimaryModelFilter): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -401,7 +401,7 @@ class DeviceTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilter, WeightFil @strawberry_django.filter_type(models.FrontPort, lookups=True) -class FrontPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): +class FrontPortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -463,7 +463,7 @@ def primary(self, value: bool, prefix) -> Q: @strawberry_django.filter_type(models.Interface, lookups=True) class InterfaceFilter( - ModularComponentModelFilterMixin, + ModularComponentFilterMixin, InterfaceBaseFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter @@ -634,7 +634,7 @@ class ManufacturerFilter(ContactFilterMixin, OrganizationalModelFilter): @strawberry_django.filter_type(models.Module, lookups=True) -class ModuleFilter(PrimaryModelFilter, ConfigContextFilterMixin): +class ModuleFilter(ConfigContextFilterMixin, PrimaryModelFilter): device: Annotated['DeviceFilter', strawberry.lazy('dcim.graphql.filters')] | None = strawberry_django.filter_field() device_id: ID | None = strawberry_django.filter_field() module_bay: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( @@ -683,7 +683,7 @@ class ModuleFilter(PrimaryModelFilter, ConfigContextFilterMixin): @strawberry_django.filter_type(models.ModuleBay, lookups=True) -class ModuleBayFilter(ModularComponentModelFilterMixin, NetBoxModelFilter): +class ModuleBayFilter(ModularComponentFilterMixin, NetBoxModelFilter): parent: Annotated['ModuleBayFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -702,7 +702,7 @@ class ModuleTypeProfileFilter(PrimaryModelFilter): @strawberry_django.filter_type(models.ModuleType, lookups=True) -class ModuleTypeFilter(ImageAttachmentFilterMixin, PrimaryModelFilter, WeightFilterMixin): +class ModuleTypeFilter(ImageAttachmentFilterMixin, WeightFilterMixin, PrimaryModelFilter): manufacturer: Annotated['ManufacturerFilter', strawberry.lazy('dcim.graphql.filters')] | None = ( strawberry_django.filter_field() ) @@ -800,7 +800,7 @@ class PowerFeedFilter(CabledObjectModelFilterMixin, TenancyFilterMixin, PrimaryM @strawberry_django.filter_type(models.PowerOutlet, lookups=True) -class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): +class PowerOutletFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -820,7 +820,7 @@ class PowerOutletFilter(ModularComponentModelFilterMixin, CabledObjectModelFilte @strawberry_django.filter_type(models.PowerOutletTemplate, lookups=True) -class PowerOutletTemplateFilter(ModularComponentModelFilterMixin, NetBoxModelFilter): +class PowerOutletTemplateFilter(ModularComponentTemplateFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -847,7 +847,7 @@ class PowerPanelFilter(ContactFilterMixin, ImageAttachmentFilterMixin, PrimaryMo @strawberry_django.filter_type(models.PowerPort, lookups=True) -class PowerPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): +class PowerPortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PowerPortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -892,6 +892,7 @@ class RackFilter( ContactFilterMixin, ImageAttachmentFilterMixin, TenancyFilterMixin, + WeightFilterMixin, RackFilterMixin, PrimaryModelFilter ): @@ -950,7 +951,7 @@ class RackRoleFilter(OrganizationalModelFilter): @strawberry_django.filter_type(models.RearPort, lookups=True) -class RearPortFilter(ModularComponentModelFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): +class RearPortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['PortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) diff --git a/netbox/ipam/graphql/filter_mixins.py b/netbox/ipam/graphql/filter_mixins.py index 36666f781f0..72d8e1404c3 100644 --- a/netbox/ipam/graphql/filter_mixins.py +++ b/netbox/ipam/graphql/filter_mixins.py @@ -3,6 +3,7 @@ import strawberry import strawberry_django +from strawberry_django import BaseFilterLookup if TYPE_CHECKING: from netbox.graphql.filter_lookups import IntegerLookup @@ -15,7 +16,7 @@ @dataclass class ServiceFilterMixin: - protocol: Annotated['ServiceProtocolEnum', strawberry.lazy('ipam.graphql.enums')] | None = ( + protocol: BaseFilterLookup[Annotated['ServiceProtocolEnum', strawberry.lazy('ipam.graphql.enums')]] | None = ( strawberry_django.filter_field() ) ports: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( diff --git a/netbox/tenancy/graphql/filters.py b/netbox/tenancy/graphql/filters.py index 4c5eaff22b1..f97106d9ba4 100644 --- a/netbox/tenancy/graphql/filters.py +++ b/netbox/tenancy/graphql/filters.py @@ -54,7 +54,7 @@ @strawberry_django.filter_type(models.Tenant, lookups=True) -class TenantFilter(PrimaryModelFilter, ContactFilterMixin): +class TenantFilter(ContactFilterMixin, PrimaryModelFilter): name: FilterLookup[str] | None = strawberry_django.filter_field() slug: FilterLookup[str] | None = strawberry_django.filter_field() group: Annotated['TenantGroupFilter', strawberry.lazy('tenancy.graphql.filters')] | None = ( From fd8f37dfe8ae1d0aeb329df43936451814c499ce Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Sun, 7 Dec 2025 12:41:28 -0500 Subject: [PATCH 6/6] Correct base models for some device component filters --- netbox/dcim/graphql/filters.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/netbox/dcim/graphql/filters.py b/netbox/dcim/graphql/filters.py index ff2f89886ac..53a385e6f15 100644 --- a/netbox/dcim/graphql/filters.py +++ b/netbox/dcim/graphql/filters.py @@ -127,7 +127,7 @@ class CableTerminationFilter(ChangeLoggedModelFilter): @strawberry_django.filter_type(models.ConsolePort, lookups=True) -class ConsolePortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, ChangeLoggedModelFilter): +class ConsolePortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -144,11 +144,7 @@ class ConsolePortTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLogge @strawberry_django.filter_type(models.ConsoleServerPort, lookups=True) -class ConsoleServerPortFilter( - ModularComponentFilterMixin, - CabledObjectModelFilterMixin, - ChangeLoggedModelFilter -): +class ConsoleServerPortFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixin, NetBoxModelFilter): type: BaseFilterLookup[Annotated['ConsolePortTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() ) @@ -820,7 +816,7 @@ class PowerOutletFilter(ModularComponentFilterMixin, CabledObjectModelFilterMixi @strawberry_django.filter_type(models.PowerOutletTemplate, lookups=True) -class PowerOutletTemplateFilter(ModularComponentTemplateFilterMixin, NetBoxModelFilter): +class PowerOutletTemplateFilter(ModularComponentTemplateFilterMixin, ChangeLoggedModelFilter): type: BaseFilterLookup[Annotated['PowerOutletTypeEnum', strawberry.lazy('dcim.graphql.enums')]] | None = ( strawberry_django.filter_field() )