Add owner filters

This commit is contained in:
Jeremy Stretch
2025-10-21 10:26:48 -04:00
parent 789139b88a
commit 800cf5cf3d
11 changed files with 111 additions and 101 deletions

View File

@@ -6,7 +6,7 @@ from django.utils.translation import gettext as _
from dcim.filtersets import CabledObjectFilterSet from dcim.filtersets import CabledObjectFilterSet
from dcim.models import Interface, Location, Region, Site, SiteGroup from dcim.models import Interface, Location, Region, Site, SiteGroup
from ipam.models import ASN from ipam.models import ASN
from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import ( from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, TreeNodeMultipleChoiceFilter, ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter, TreeNodeMultipleChoiceFilter,
@@ -29,7 +29,7 @@ __all__ = (
) )
class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): class ProviderFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
region_id = TreeNodeMultipleChoiceFilter( region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
field_name='circuits__terminations___region', field_name='circuits__terminations___region',
@@ -95,7 +95,7 @@ class ProviderFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
) )
class ProviderAccountFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): class ProviderAccountFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
provider_id = django_filters.ModelMultipleChoiceFilter( provider_id = django_filters.ModelMultipleChoiceFilter(
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
label=_('Provider (ID)'), label=_('Provider (ID)'),
@@ -122,7 +122,7 @@ class ProviderAccountFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
).distinct() ).distinct()
class ProviderNetworkFilterSet(NetBoxModelFilterSet): class ProviderNetworkFilterSet(PrimaryModelFilterSet):
provider_id = django_filters.ModelMultipleChoiceFilter( provider_id = django_filters.ModelMultipleChoiceFilter(
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
label=_('Provider (ID)'), label=_('Provider (ID)'),
@@ -156,7 +156,7 @@ class CircuitTypeFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'color', 'description') fields = ('id', 'name', 'slug', 'color', 'description')
class CircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
provider_id = django_filters.ModelMultipleChoiceFilter( provider_id = django_filters.ModelMultipleChoiceFilter(
queryset=Provider.objects.all(), queryset=Provider.objects.all(),
label=_('Provider (ID)'), label=_('Provider (ID)'),
@@ -475,7 +475,7 @@ class VirtualCircuitTypeFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'color', 'description') fields = ('id', 'name', 'slug', 'color', 'description')
class VirtualCircuitFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class VirtualCircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
provider_id = django_filters.ModelMultipleChoiceFilter( provider_id = django_filters.ModelMultipleChoiceFilter(
field_name='provider_network__provider', field_name='provider_network__provider',
queryset=Provider.objects.all(), queryset=Provider.objects.all(),

View File

@@ -3,7 +3,7 @@ from django.contrib.contenttypes.models import ContentType
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, NetBoxModelFilterSet from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, PrimaryModelFilterSet
from netbox.utils import get_data_backend_choices from netbox.utils import get_data_backend_choices
from users.models import User from users.models import User
from utilities.filters import ContentTypeFilter from utilities.filters import ContentTypeFilter
@@ -20,7 +20,7 @@ __all__ = (
) )
class DataSourceFilterSet(NetBoxModelFilterSet): class DataSourceFilterSet(PrimaryModelFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=get_data_backend_choices, choices=get_data_backend_choices,
null_value=None null_value=None

View File

@@ -11,8 +11,8 @@ from ipam.filtersets import PrimaryIPFilterSet
from ipam.models import ASN, IPAddress, VLANTranslationPolicy, VRF from ipam.models import ASN, IPAddress, VLANTranslationPolicy, VRF
from netbox.choices import ColorChoices from netbox.choices import ColorChoices
from netbox.filtersets import ( from netbox.filtersets import (
AttributeFiltersMixin, BaseFilterSet, ChangeLoggedModelFilterSet, NestedGroupModelFilterSet, NetBoxModelFilterSet, AttributeFiltersMixin, BaseFilterSet, ChangeLoggedModelFilterSet, NestedGroupModelFilterSet,
OrganizationalModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
) )
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
from tenancy.models import * from tenancy.models import *
@@ -143,7 +143,7 @@ class SiteGroupFilterSet(NestedGroupModelFilterSet, ContactModelFilterSet):
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class SiteFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
status = django_filters.MultipleChoiceFilter( status = django_filters.MultipleChoiceFilter(
choices=SiteStatusChoices, choices=SiteStatusChoices,
null_value=None null_value=None
@@ -293,7 +293,7 @@ class RackRoleFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'color', 'description') fields = ('id', 'name', 'slug', 'color', 'description')
class RackTypeFilterSet(NetBoxModelFilterSet): class RackTypeFilterSet(PrimaryModelFilterSet):
manufacturer_id = django_filters.ModelMultipleChoiceFilter( manufacturer_id = django_filters.ModelMultipleChoiceFilter(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
label=_('Manufacturer (ID)'), label=_('Manufacturer (ID)'),
@@ -328,7 +328,7 @@ class RackTypeFilterSet(NetBoxModelFilterSet):
) )
class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
region_id = TreeNodeMultipleChoiceFilter( region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
field_name='site__region', field_name='site__region',
@@ -444,7 +444,7 @@ class RackFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSe
) )
class RackReservationFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class RackReservationFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
rack_id = django_filters.ModelMultipleChoiceFilter( rack_id = django_filters.ModelMultipleChoiceFilter(
queryset=Rack.objects.all(), queryset=Rack.objects.all(),
label=_('Rack (ID)'), label=_('Rack (ID)'),
@@ -540,7 +540,7 @@ class ManufacturerFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet)
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class DeviceTypeFilterSet(NetBoxModelFilterSet): class DeviceTypeFilterSet(PrimaryModelFilterSet):
manufacturer_id = django_filters.ModelMultipleChoiceFilter( manufacturer_id = django_filters.ModelMultipleChoiceFilter(
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
label=_('Manufacturer (ID)'), label=_('Manufacturer (ID)'),
@@ -682,7 +682,7 @@ class DeviceTypeFilterSet(NetBoxModelFilterSet):
return queryset.exclude(inventoryitemtemplates__isnull=value) return queryset.exclude(inventoryitemtemplates__isnull=value)
class ModuleTypeProfileFilterSet(NetBoxModelFilterSet): class ModuleTypeProfileFilterSet(PrimaryModelFilterSet):
class Meta: class Meta:
model = ModuleTypeProfile model = ModuleTypeProfile
@@ -698,7 +698,7 @@ class ModuleTypeProfileFilterSet(NetBoxModelFilterSet):
) )
class ModuleTypeFilterSet(AttributeFiltersMixin, NetBoxModelFilterSet): class ModuleTypeFilterSet(AttributeFiltersMixin, PrimaryModelFilterSet):
profile_id = django_filters.ModelMultipleChoiceFilter( profile_id = django_filters.ModelMultipleChoiceFilter(
queryset=ModuleTypeProfile.objects.all(), queryset=ModuleTypeProfile.objects.all(),
label=_('Profile (ID)'), label=_('Profile (ID)'),
@@ -1043,7 +1043,7 @@ class PlatformFilterSet(OrganizationalModelFilterSet):
class DeviceFilterSet( class DeviceFilterSet(
NetBoxModelFilterSet, PrimaryModelFilterSet,
TenancyFilterSet, TenancyFilterSet,
ContactModelFilterSet, ContactModelFilterSet,
LocalConfigContextFilterSet, LocalConfigContextFilterSet,
@@ -1345,7 +1345,7 @@ class DeviceFilterSet(
return queryset.exclude(params) return queryset.exclude(params)
class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet): class VirtualDeviceContextFilterSet(PrimaryModelFilterSet, TenancyFilterSet, PrimaryIPFilterSet):
device_id = django_filters.ModelMultipleChoiceFilter( device_id = django_filters.ModelMultipleChoiceFilter(
field_name='device', field_name='device',
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -1394,7 +1394,7 @@ class VirtualDeviceContextFilterSet(NetBoxModelFilterSet, TenancyFilterSet, Prim
return queryset.exclude(params) return queryset.exclude(params)
class ModuleFilterSet(NetBoxModelFilterSet): class ModuleFilterSet(PrimaryModelFilterSet):
manufacturer_id = django_filters.ModelMultipleChoiceFilter( manufacturer_id = django_filters.ModelMultipleChoiceFilter(
field_name='module_type__manufacturer', field_name='module_type__manufacturer',
queryset=Manufacturer.objects.all(), queryset=Manufacturer.objects.all(),
@@ -1516,7 +1516,7 @@ class ModuleFilterSet(NetBoxModelFilterSet):
).distinct() ).distinct()
class DeviceComponentFilterSet(django_filters.FilterSet): class DeviceComponentFilterSet(PrimaryModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label=_('Search'), label=_('Search'),
@@ -1682,12 +1682,7 @@ class PathEndpointFilterSet(django_filters.FilterSet):
return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False)) return queryset.filter(Q(_path__isnull=True) | Q(_path__is_active=False))
class ConsolePortFilterSet( class ConsolePortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet,
PathEndpointFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
null_value=None null_value=None
@@ -1698,12 +1693,7 @@ class ConsolePortFilterSet(
fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end') fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end')
class ConsoleServerPortFilterSet( class ConsoleServerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet,
PathEndpointFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices, choices=ConsolePortTypeChoices,
null_value=None null_value=None
@@ -1714,12 +1704,7 @@ class ConsoleServerPortFilterSet(
fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end') fields = ('id', 'name', 'label', 'speed', 'description', 'mark_connected', 'cable_end')
class PowerPortFilterSet( class PowerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet,
PathEndpointFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PowerPortTypeChoices, choices=PowerPortTypeChoices,
null_value=None null_value=None
@@ -1732,12 +1717,7 @@ class PowerPortFilterSet(
) )
class PowerOutletFilterSet( class PowerOutletFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet,
PathEndpointFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PowerOutletTypeChoices, choices=PowerOutletTypeChoices,
null_value=None null_value=None
@@ -1762,7 +1742,7 @@ class PowerOutletFilterSet(
) )
class MACAddressFilterSet(NetBoxModelFilterSet): class MACAddressFilterSet(PrimaryModelFilterSet):
mac_address = MultiValueMACAddressFilter() mac_address = MultiValueMACAddressFilter()
assigned_object_type = ContentTypeFilter() assigned_object_type = ContentTypeFilter()
device = MultiValueCharFilter( device = MultiValueCharFilter(
@@ -1914,7 +1894,6 @@ class CommonInterfaceFilterSet(django_filters.FilterSet):
class InterfaceFilterSet( class InterfaceFilterSet(
ModularDeviceComponentFilterSet, ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet, CabledObjectFilterSet,
PathEndpointFilterSet, PathEndpointFilterSet,
CommonInterfaceFilterSet CommonInterfaceFilterSet
@@ -2075,11 +2054,7 @@ class InterfaceFilterSet(
) )
class FrontPortFilterSet( class FrontPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet):
ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices, choices=PortTypeChoices,
null_value=None null_value=None
@@ -2095,11 +2070,7 @@ class FrontPortFilterSet(
) )
class RearPortFilterSet( class RearPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet):
ModularDeviceComponentFilterSet,
NetBoxModelFilterSet,
CabledObjectFilterSet
):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices, choices=PortTypeChoices,
null_value=None null_value=None
@@ -2112,7 +2083,7 @@ class RearPortFilterSet(
) )
class ModuleBayFilterSet(ModularDeviceComponentFilterSet, NetBoxModelFilterSet): class ModuleBayFilterSet(ModularDeviceComponentFilterSet):
parent_id = django_filters.ModelMultipleChoiceFilter( parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=ModuleBay.objects.all(), queryset=ModuleBay.objects.all(),
label=_('Parent module bay (ID)'), label=_('Parent module bay (ID)'),
@@ -2128,7 +2099,7 @@ class ModuleBayFilterSet(ModularDeviceComponentFilterSet, NetBoxModelFilterSet):
fields = ('id', 'name', 'label', 'position', 'description') fields = ('id', 'name', 'label', 'position', 'description')
class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): class DeviceBayFilterSet(DeviceComponentFilterSet):
installed_device_id = django_filters.ModelMultipleChoiceFilter( installed_device_id = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(), queryset=Device.objects.all(),
label=_('Installed device (ID)'), label=_('Installed device (ID)'),
@@ -2145,7 +2116,7 @@ class DeviceBayFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet):
fields = ('id', 'name', 'label', 'description') fields = ('id', 'name', 'label', 'description')
class InventoryItemFilterSet(DeviceComponentFilterSet, NetBoxModelFilterSet): class InventoryItemFilterSet(DeviceComponentFilterSet):
parent_id = django_filters.ModelMultipleChoiceFilter( parent_id = django_filters.ModelMultipleChoiceFilter(
queryset=InventoryItem.objects.all(), queryset=InventoryItem.objects.all(),
label=_('Parent inventory item (ID)'), label=_('Parent inventory item (ID)'),
@@ -2204,7 +2175,7 @@ class InventoryItemRoleFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'color', 'description') fields = ('id', 'name', 'slug', 'color', 'description')
class VirtualChassisFilterSet(NetBoxModelFilterSet): class VirtualChassisFilterSet(PrimaryModelFilterSet):
master_id = django_filters.ModelMultipleChoiceFilter( master_id = django_filters.ModelMultipleChoiceFilter(
queryset=Device.objects.all(), queryset=Device.objects.all(),
label=_('Master (ID)'), label=_('Master (ID)'),
@@ -2280,7 +2251,7 @@ class VirtualChassisFilterSet(NetBoxModelFilterSet):
return queryset.filter(qs_filter).distinct() return queryset.filter(qs_filter).distinct()
class CableFilterSet(TenancyFilterSet, NetBoxModelFilterSet): class CableFilterSet(TenancyFilterSet, PrimaryModelFilterSet):
termination_a_type = ContentTypeFilter( termination_a_type = ContentTypeFilter(
field_name='terminations__termination_type' field_name='terminations__termination_type'
) )
@@ -2457,7 +2428,7 @@ class CableTerminationFilterSet(ChangeLoggedModelFilterSet):
fields = ('id', 'cable', 'cable_end', 'termination_type', 'termination_id') fields = ('id', 'cable', 'cable_end', 'termination_type', 'termination_id')
class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): class PowerPanelFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
region_id = TreeNodeMultipleChoiceFilter( region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
field_name='site__region', field_name='site__region',
@@ -2515,7 +2486,7 @@ class PowerPanelFilterSet(NetBoxModelFilterSet, ContactModelFilterSet):
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class PowerFeedFilterSet(NetBoxModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet): class PowerFeedFilterSet(PrimaryModelFilterSet, CabledObjectFilterSet, PathEndpointFilterSet, TenancyFilterSet):
region_id = TreeNodeMultipleChoiceFilter( region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
field_name='power_panel__site__region', field_name='power_panel__site__region',

View File

@@ -7,6 +7,7 @@ from core.models import DataSource, ObjectType
from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup from dcim.models import DeviceRole, DeviceType, Location, Platform, Region, Site, SiteGroup
from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, NetBoxModelFilterSet from netbox.filtersets import BaseFilterSet, ChangeLoggedModelFilterSet, NetBoxModelFilterSet
from tenancy.models import Tenant, TenantGroup from tenancy.models import Tenant, TenantGroup
from users.filterset_mixins import OwnerFilterMixin
from users.models import Group, User from users.models import Group, User
from utilities.filters import ( from utilities.filters import (
ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
@@ -619,7 +620,7 @@ class ConfigContextProfileFilterSet(NetBoxModelFilterSet):
) )
class ConfigContextFilterSet(ChangeLoggedModelFilterSet): class ConfigContextFilterSet(OwnerFilterMixin, ChangeLoggedModelFilterSet):
q = django_filters.CharFilter( q = django_filters.CharFilter(
method='search', method='search',
label=_('Search'), label=_('Search'),

View File

@@ -11,7 +11,9 @@ from netaddr.core import AddrFormatError
from circuits.models import Provider from circuits.models import Provider
from dcim.models import Device, Interface, Region, Site, SiteGroup from dcim.models import Device, Interface, Region, Site, SiteGroup
from netbox.filtersets import ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet from netbox.filtersets import (
ChangeLoggedModelFilterSet, OrganizationalModelFilterSet, NetBoxModelFilterSet, PrimaryModelFilterSet,
)
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import ( from utilities.filters import (
@@ -45,7 +47,7 @@ __all__ = (
) )
class VRFFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class VRFFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
import_target_id = django_filters.ModelMultipleChoiceFilter( import_target_id = django_filters.ModelMultipleChoiceFilter(
field_name='import_targets', field_name='import_targets',
queryset=RouteTarget.objects.all(), queryset=RouteTarget.objects.all(),
@@ -83,7 +85,7 @@ class VRFFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
fields = ('id', 'name', 'rd', 'enforce_unique', 'description') fields = ('id', 'name', 'rd', 'enforce_unique', 'description')
class RouteTargetFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class RouteTargetFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
importing_vrf_id = django_filters.ModelMultipleChoiceFilter( importing_vrf_id = django_filters.ModelMultipleChoiceFilter(
field_name='importing_vrfs', field_name='importing_vrfs',
queryset=VRF.objects.all(), queryset=VRF.objects.all(),
@@ -149,7 +151,7 @@ class RIRFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'is_private', 'description') fields = ('id', 'name', 'slug', 'is_private', 'description')
class AggregateFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class AggregateFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter( family = django_filters.NumberFilter(
field_name='prefix', field_name='prefix',
lookup_expr='family' lookup_expr='family'
@@ -221,7 +223,7 @@ class ASNRangeFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
) )
class ASNFilterSet(OrganizationalModelFilterSet, TenancyFilterSet): class ASNFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
rir_id = django_filters.ModelMultipleChoiceFilter( rir_id = django_filters.ModelMultipleChoiceFilter(
queryset=RIR.objects.all(), queryset=RIR.objects.all(),
label=_('RIR (ID)'), label=_('RIR (ID)'),
@@ -290,7 +292,7 @@ class RoleFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'description', 'weight') fields = ('id', 'name', 'slug', 'description', 'weight')
class PrefixFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterSet, ContactModelFilterSet): class PrefixFilterSet(PrimaryModelFilterSet, ScopedFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter( family = django_filters.NumberFilter(
field_name='prefix', field_name='prefix',
lookup_expr='family' lookup_expr='family'
@@ -456,7 +458,7 @@ class PrefixFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterSet, C
).distinct() ).distinct()
class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet, ContactModelFilterSet): class IPRangeFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter( family = django_filters.NumberFilter(
field_name='start_address', field_name='start_address',
lookup_expr='family' lookup_expr='family'
@@ -548,7 +550,7 @@ class IPRangeFilterSet(TenancyFilterSet, NetBoxModelFilterSet, ContactModelFilte
return queryset.filter(q) return queryset.filter(q)
class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class IPAddressFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
family = django_filters.NumberFilter( family = django_filters.NumberFilter(
field_name='address', field_name='address',
lookup_expr='family' lookup_expr='family'
@@ -784,7 +786,7 @@ class IPAddressFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFil
) )
class FHRPGroupFilterSet(NetBoxModelFilterSet): class FHRPGroupFilterSet(PrimaryModelFilterSet):
protocol = django_filters.MultipleChoiceFilter( protocol = django_filters.MultipleChoiceFilter(
choices=FHRPGroupProtocolChoices choices=FHRPGroupProtocolChoices
) )
@@ -934,7 +936,7 @@ class VLANGroupFilterSet(OrganizationalModelFilterSet, TenancyFilterSet):
) )
class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
region_id = TreeNodeMultipleChoiceFilter( region_id = TreeNodeMultipleChoiceFilter(
queryset=Region.objects.all(), queryset=Region.objects.all(),
field_name='site__region', field_name='site__region',
@@ -1085,7 +1087,7 @@ class VLANFilterSet(NetBoxModelFilterSet, TenancyFilterSet):
).distinct() ).distinct()
class VLANTranslationPolicyFilterSet(NetBoxModelFilterSet): class VLANTranslationPolicyFilterSet(PrimaryModelFilterSet):
class Meta: class Meta:
model = VLANTranslationPolicy model = VLANTranslationPolicy
@@ -1132,7 +1134,7 @@ class VLANTranslationRuleFilterSet(NetBoxModelFilterSet):
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class ServiceTemplateFilterSet(NetBoxModelFilterSet): class ServiceTemplateFilterSet(PrimaryModelFilterSet):
port = NumericArrayFilter( port = NumericArrayFilter(
field_name='ports', field_name='ports',
lookup_expr='contains' lookup_expr='contains'
@@ -1152,7 +1154,7 @@ class ServiceTemplateFilterSet(NetBoxModelFilterSet):
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class ServiceFilterSet(ContactModelFilterSet, NetBoxModelFilterSet): class ServiceFilterSet(ContactModelFilterSet, PrimaryModelFilterSet):
parent_object_type = ContentTypeFilter() parent_object_type = ContentTypeFilter()
device = MultiValueCharFilter( device = MultiValueCharFilter(
method='filter_device', method='filter_device',

View File

@@ -14,6 +14,7 @@ from core.models import ObjectChange
from extras.choices import CustomFieldFilterLogicChoices from extras.choices import CustomFieldFilterLogicChoices
from extras.filters import TagFilter, TagIDFilter from extras.filters import TagFilter, TagIDFilter
from extras.models import CustomField, SavedFilter from extras.models import CustomField, SavedFilter
from users.filterset_mixins import OwnerFilterMixin
from utilities.constants import ( from utilities.constants import (
FILTER_CHAR_BASED_LOOKUP_MAP, FILTER_NEGATION_LOOKUP_MAP, FILTER_TREENODE_NEGATION_LOOKUP_MAP, FILTER_CHAR_BASED_LOOKUP_MAP, FILTER_NEGATION_LOOKUP_MAP, FILTER_TREENODE_NEGATION_LOOKUP_MAP,
FILTER_NUMERIC_BASED_LOOKUP_MAP FILTER_NUMERIC_BASED_LOOKUP_MAP
@@ -25,8 +26,10 @@ __all__ = (
'AttributeFiltersMixin', 'AttributeFiltersMixin',
'BaseFilterSet', 'BaseFilterSet',
'ChangeLoggedModelFilterSet', 'ChangeLoggedModelFilterSet',
'NestedGroupModelFilterSet',
'NetBoxModelFilterSet', 'NetBoxModelFilterSet',
'OrganizationalModelFilterSet', 'OrganizationalModelFilterSet',
'PrimaryModelFilterSet',
) )
STANDARD_LOOKUPS = ( STANDARD_LOOKUPS = (
@@ -328,9 +331,16 @@ class NetBoxModelFilterSet(ChangeLoggedModelFilterSet):
return queryset return queryset
class OrganizationalModelFilterSet(NetBoxModelFilterSet): class PrimaryModelFilterSet(OwnerFilterMixin, NetBoxModelFilterSet):
""" """
A base class for adding the search method to models which only expose the `name` and `slug` fields Base filterset for models inheriting from PrimaryModel.
"""
pass
class OrganizationalModelFilterSet(OwnerFilterMixin, NetBoxModelFilterSet):
"""
Base filterset for models inheriting from OrganizationalModel.
""" """
def search(self, queryset, name, value): def search(self, queryset, name, value):
if not value.strip(): if not value.strip():
@@ -342,9 +352,9 @@ class OrganizationalModelFilterSet(NetBoxModelFilterSet):
) )
class NestedGroupModelFilterSet(NetBoxModelFilterSet): class NestedGroupModelFilterSet(OwnerFilterMixin, NetBoxModelFilterSet):
""" """
A base FilterSet for models that inherit from NestedGroupModel Base filterset for models inheriting from NestedGroupModel.
""" """
def search(self, queryset, name, value): def search(self, queryset, name, value):
if value.strip(): if value.strip():

View File

@@ -2,7 +2,9 @@ import django_filters
from django.db.models import Q from django.db.models import Q
from django.utils.translation import gettext as _ from django.utils.translation import gettext as _
from netbox.filtersets import NestedGroupModelFilterSet, NetBoxModelFilterSet, OrganizationalModelFilterSet from netbox.filtersets import (
NestedGroupModelFilterSet, NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet,
)
from utilities.filters import ContentTypeFilter, TreeNodeMultipleChoiceFilter from utilities.filters import ContentTypeFilter, TreeNodeMultipleChoiceFilter
from .models import * from .models import *
@@ -64,7 +66,7 @@ class ContactRoleFilterSet(OrganizationalModelFilterSet):
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class ContactFilterSet(NetBoxModelFilterSet): class ContactFilterSet(PrimaryModelFilterSet):
group_id = TreeNodeMultipleChoiceFilter( group_id = TreeNodeMultipleChoiceFilter(
queryset=ContactGroup.objects.all(), queryset=ContactGroup.objects.all(),
field_name='groups', field_name='groups',
@@ -198,7 +200,7 @@ class TenantGroupFilterSet(NestedGroupModelFilterSet):
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class TenantFilterSet(NetBoxModelFilterSet, ContactModelFilterSet): class TenantFilterSet(PrimaryModelFilterSet, ContactModelFilterSet):
group_id = TreeNodeMultipleChoiceFilter( group_id = TreeNodeMultipleChoiceFilter(
queryset=TenantGroup.objects.all(), queryset=TenantGroup.objects.all(),
field_name='group', field_name='group',

View File

@@ -0,0 +1,24 @@
import django_filters
from django.utils.translation import gettext as _
from users.models import Owner
__all__ = (
'OwnerFilterMixin',
)
class OwnerFilterMixin(django_filters.FilterSet):
"""
Adds owner & owner_id filters for models which inherit from OwnerMixin.
"""
owner_id = django_filters.ModelMultipleChoiceFilter(
queryset=Owner.objects.all(),
label=_('Owner (ID)'),
)
owner = django_filters.ModelMultipleChoiceFilter(
field_name='owner__name',
queryset=Owner.objects.all(),
to_field_name='name',
label=_('Owner (name)'),
)

View File

@@ -9,7 +9,7 @@ from dcim.models import MACAddress
from extras.filtersets import LocalConfigContextFilterSet from extras.filtersets import LocalConfigContextFilterSet
from extras.models import ConfigTemplate from extras.models import ConfigTemplate
from ipam.filtersets import PrimaryIPFilterSet from ipam.filtersets import PrimaryIPFilterSet
from netbox.filtersets import OrganizationalModelFilterSet, NetBoxModelFilterSet from netbox.filtersets import OrganizationalModelFilterSet, PrimaryModelFilterSet
from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet from tenancy.filtersets import TenancyFilterSet, ContactModelFilterSet
from utilities.filters import MultiValueCharFilter, MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter from utilities.filters import MultiValueCharFilter, MultiValueMACAddressFilter, TreeNodeMultipleChoiceFilter
from .choices import * from .choices import *
@@ -39,7 +39,7 @@ class ClusterGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet)
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class ClusterFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ScopedFilterSet, ContactModelFilterSet): class ClusterFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ScopedFilterSet, ContactModelFilterSet):
group_id = django_filters.ModelMultipleChoiceFilter( group_id = django_filters.ModelMultipleChoiceFilter(
queryset=ClusterGroup.objects.all(), queryset=ClusterGroup.objects.all(),
label=_('Parent group (ID)'), label=_('Parent group (ID)'),
@@ -80,7 +80,7 @@ class ClusterFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ScopedFilterSet,
class VirtualMachineFilterSet( class VirtualMachineFilterSet(
NetBoxModelFilterSet, PrimaryModelFilterSet,
TenancyFilterSet, TenancyFilterSet,
ContactModelFilterSet, ContactModelFilterSet,
LocalConfigContextFilterSet, LocalConfigContextFilterSet,
@@ -235,7 +235,7 @@ class VirtualMachineFilterSet(
return queryset.exclude(params) return queryset.exclude(params)
class VMInterfaceFilterSet(NetBoxModelFilterSet, CommonInterfaceFilterSet): class VMInterfaceFilterSet(PrimaryModelFilterSet, CommonInterfaceFilterSet):
cluster_id = django_filters.ModelMultipleChoiceFilter( cluster_id = django_filters.ModelMultipleChoiceFilter(
field_name='virtual_machine__cluster', field_name='virtual_machine__cluster',
queryset=Cluster.objects.all(), queryset=Cluster.objects.all(),
@@ -297,7 +297,7 @@ class VMInterfaceFilterSet(NetBoxModelFilterSet, CommonInterfaceFilterSet):
) )
class VirtualDiskFilterSet(NetBoxModelFilterSet): class VirtualDiskFilterSet(PrimaryModelFilterSet):
virtual_machine_id = django_filters.ModelMultipleChoiceFilter( virtual_machine_id = django_filters.ModelMultipleChoiceFilter(
field_name='virtual_machine', field_name='virtual_machine',
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),

View File

@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
from dcim.models import Device, Interface from dcim.models import Device, Interface
from ipam.models import IPAddress, RouteTarget, VLAN from ipam.models import IPAddress, RouteTarget, VLAN
from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet from netbox.filtersets import NetBoxModelFilterSet, OrganizationalModelFilterSet, PrimaryModelFilterSet
from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet from tenancy.filtersets import ContactModelFilterSet, TenancyFilterSet
from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter from utilities.filters import ContentTypeFilter, MultiValueCharFilter, MultiValueNumberFilter
from virtualization.models import VirtualMachine, VMInterface from virtualization.models import VirtualMachine, VMInterface
@@ -32,7 +32,7 @@ class TunnelGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class TunnelFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class TunnelFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
status = django_filters.MultipleChoiceFilter( status = django_filters.MultipleChoiceFilter(
choices=TunnelStatusChoices choices=TunnelStatusChoices
) )
@@ -123,7 +123,7 @@ class TunnelTerminationFilterSet(NetBoxModelFilterSet):
fields = ('id', 'termination_id') fields = ('id', 'termination_id')
class IKEProposalFilterSet(NetBoxModelFilterSet): class IKEProposalFilterSet(PrimaryModelFilterSet):
ike_policy_id = django_filters.ModelMultipleChoiceFilter( ike_policy_id = django_filters.ModelMultipleChoiceFilter(
field_name='ike_policies', field_name='ike_policies',
queryset=IKEPolicy.objects.all(), queryset=IKEPolicy.objects.all(),
@@ -162,7 +162,7 @@ class IKEProposalFilterSet(NetBoxModelFilterSet):
) )
class IKEPolicyFilterSet(NetBoxModelFilterSet): class IKEPolicyFilterSet(PrimaryModelFilterSet):
version = django_filters.MultipleChoiceFilter( version = django_filters.MultipleChoiceFilter(
choices=IKEVersionChoices choices=IKEVersionChoices
) )
@@ -193,7 +193,7 @@ class IKEPolicyFilterSet(NetBoxModelFilterSet):
) )
class IPSecProposalFilterSet(NetBoxModelFilterSet): class IPSecProposalFilterSet(PrimaryModelFilterSet):
ipsec_policy_id = django_filters.ModelMultipleChoiceFilter( ipsec_policy_id = django_filters.ModelMultipleChoiceFilter(
field_name='ipsec_policies', field_name='ipsec_policies',
queryset=IPSecPolicy.objects.all(), queryset=IPSecPolicy.objects.all(),
@@ -226,7 +226,7 @@ class IPSecProposalFilterSet(NetBoxModelFilterSet):
) )
class IPSecPolicyFilterSet(NetBoxModelFilterSet): class IPSecPolicyFilterSet(PrimaryModelFilterSet):
pfs_group = django_filters.MultipleChoiceFilter( pfs_group = django_filters.MultipleChoiceFilter(
choices=DHGroupChoices choices=DHGroupChoices
) )
@@ -254,7 +254,7 @@ class IPSecPolicyFilterSet(NetBoxModelFilterSet):
) )
class IPSecProfileFilterSet(NetBoxModelFilterSet): class IPSecProfileFilterSet(PrimaryModelFilterSet):
mode = django_filters.MultipleChoiceFilter( mode = django_filters.MultipleChoiceFilter(
choices=IPSecModeChoices choices=IPSecModeChoices
) )
@@ -293,7 +293,7 @@ class IPSecProfileFilterSet(NetBoxModelFilterSet):
) )
class L2VPNFilterSet(NetBoxModelFilterSet, TenancyFilterSet, ContactModelFilterSet): class L2VPNFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
type = django_filters.MultipleChoiceFilter( type = django_filters.MultipleChoiceFilter(
choices=L2VPNTypeChoices, choices=L2VPNTypeChoices,
null_value=None null_value=None

View File

@@ -5,7 +5,7 @@ from dcim.choices import LinkStatusChoices
from dcim.base_filtersets import ScopedFilterSet from dcim.base_filtersets import ScopedFilterSet
from dcim.models import Interface from dcim.models import Interface
from ipam.models import VLAN from ipam.models import VLAN
from netbox.filtersets import NestedGroupModelFilterSet, NetBoxModelFilterSet from netbox.filtersets import NestedGroupModelFilterSet, PrimaryModelFilterSet
from tenancy.filtersets import TenancyFilterSet from tenancy.filtersets import TenancyFilterSet
from utilities.filters import TreeNodeMultipleChoiceFilter from utilities.filters import TreeNodeMultipleChoiceFilter
from .choices import * from .choices import *
@@ -44,7 +44,7 @@ class WirelessLANGroupFilterSet(NestedGroupModelFilterSet):
fields = ('id', 'name', 'slug', 'description') fields = ('id', 'name', 'slug', 'description')
class WirelessLANFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterSet): class WirelessLANFilterSet(PrimaryModelFilterSet, ScopedFilterSet, TenancyFilterSet):
group_id = TreeNodeMultipleChoiceFilter( group_id = TreeNodeMultipleChoiceFilter(
queryset=WirelessLANGroup.objects.all(), queryset=WirelessLANGroup.objects.all(),
field_name='group', field_name='group',
@@ -87,7 +87,7 @@ class WirelessLANFilterSet(NetBoxModelFilterSet, ScopedFilterSet, TenancyFilterS
return queryset.filter(qs_filter) return queryset.filter(qs_filter)
class WirelessLinkFilterSet(NetBoxModelFilterSet, TenancyFilterSet): class WirelessLinkFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
interface_a_id = django_filters.ModelMultipleChoiceFilter( interface_a_id = django_filters.ModelMultipleChoiceFilter(
queryset=Interface.objects.all() queryset=Interface.objects.all()
) )