Pass distinct=False to all MultipleChoiceFilters associated with a concrete model

This commit is contained in:
Jeremy Stretch
2026-02-12 16:00:47 -05:00
parent 440793c604
commit 79d963249d
8 changed files with 127 additions and 44 deletions

View File

@@ -209,6 +209,7 @@ class CircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilt
)
status = django_filters.MultipleChoiceFilter(
choices=CircuitStatusChoices,
distinct=False,
null_value=None
)
region_id = TreeNodeMultipleChoiceFilter(
@@ -550,6 +551,7 @@ class VirtualCircuitFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=CircuitStatusChoices,
distinct=False,
null_value=None
)
@@ -580,6 +582,7 @@ class VirtualCircuitTerminationFilterSet(NetBoxModelFilterSet):
)
role = django_filters.MultipleChoiceFilter(
choices=VirtualCircuitTerminationRoleChoices,
distinct=False,
null_value=None
)
provider_id = django_filters.ModelMultipleChoiceFilter(

View File

@@ -25,14 +25,17 @@ __all__ = (
class DataSourceFilterSet(PrimaryModelFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=get_data_backend_choices,
distinct=False,
null_value=None
)
status = django_filters.MultipleChoiceFilter(
choices=DataSourceStatusChoices,
distinct=False,
null_value=None
)
sync_interval = django_filters.MultipleChoiceFilter(
choices=JobIntervalChoices,
distinct=False,
null_value=None
)
@@ -130,6 +133,7 @@ class JobFilterSet(BaseFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=JobStatusChoices,
distinct=False,
null_value=None
)
queue_name = django_filters.CharFilter()

View File

@@ -155,6 +155,7 @@ class SiteGroupFilterSet(NestedGroupModelFilterSet, ContactModelFilterSet):
class SiteFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
status = django_filters.MultipleChoiceFilter(
choices=SiteStatusChoices,
distinct=False,
null_value=None
)
region_id = TreeNodeMultipleChoiceFilter(
@@ -283,6 +284,7 @@ class LocationFilterSet(TenancyFilterSet, ContactModelFilterSet, NestedGroupMode
)
status = django_filters.MultipleChoiceFilter(
choices=LocationStatusChoices,
distinct=False,
null_value=None
)
@@ -323,10 +325,12 @@ class RackTypeFilterSet(PrimaryModelFilterSet):
label=_('Manufacturer (slug)'),
)
form_factor = django_filters.MultipleChoiceFilter(
choices=RackFormFactorChoices
choices=RackFormFactorChoices,
distinct=False,
)
width = django_filters.MultipleChoiceFilter(
choices=RackWidthChoices
choices=RackWidthChoices,
distinct=False,
)
class Meta:
@@ -429,13 +433,16 @@ class RackFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterS
)
status = django_filters.MultipleChoiceFilter(
choices=RackStatusChoices,
distinct=False,
null_value=None
)
form_factor = django_filters.MultipleChoiceFilter(
choices=RackFormFactorChoices
choices=RackFormFactorChoices,
distinct=False,
)
width = django_filters.MultipleChoiceFilter(
choices=RackWidthChoices
choices=RackWidthChoices,
distinct=False,
)
role_id = django_filters.ModelMultipleChoiceFilter(
queryset=RackRole.objects.all(),
@@ -535,6 +542,7 @@ class RackReservationFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=RackReservationStatusChoices,
distinct=False,
null_value=None
)
user_id = django_filters.ModelMultipleChoiceFilter(
@@ -891,6 +899,7 @@ class PowerPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeCo
class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
feed_leg = django_filters.MultipleChoiceFilter(
choices=PowerOutletFeedLegChoices,
distinct=False,
null_value=None
)
power_port_id = django_filters.ModelMultipleChoiceFilter(
@@ -908,6 +917,7 @@ class PowerOutletTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceType
class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=InterfaceTypeChoices,
distinct=False,
null_value=None
)
bridge_id = django_filters.ModelMultipleChoiceFilter(
@@ -916,13 +926,16 @@ class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeCo
distinct=False,
)
poe_mode = django_filters.MultipleChoiceFilter(
choices=InterfacePoEModeChoices
choices=InterfacePoEModeChoices,
distinct=False,
)
poe_type = django_filters.MultipleChoiceFilter(
choices=InterfacePoETypeChoices
choices=InterfacePoETypeChoices,
distinct=False,
)
rf_role = django_filters.MultipleChoiceFilter(
choices=WirelessRoleChoices
choices=WirelessRoleChoices,
distinct=False,
)
class Meta:
@@ -934,6 +947,7 @@ class InterfaceTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeCo
class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices,
distinct=False,
null_value=None
)
rear_port_id = django_filters.ModelMultipleChoiceFilter(
@@ -952,6 +966,7 @@ class FrontPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeCo
class RearPortTemplateFilterSet(ChangeLoggedModelFilterSet, ModularDeviceTypeComponentFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices,
distinct=False,
null_value=None
)
front_port_id = django_filters.ModelMultipleChoiceFilter(
@@ -1288,6 +1303,7 @@ class DeviceFilterSet(
)
status = django_filters.MultipleChoiceFilter(
choices=DeviceStatusChoices,
distinct=False,
null_value=None
)
is_full_depth = django_filters.BooleanFilter(
@@ -1469,7 +1485,8 @@ class VirtualDeviceContextFilterSet(PrimaryModelFilterSet, TenancyFilterSet, Pri
label=_('Interface (ID)')
)
status = django_filters.MultipleChoiceFilter(
choices=VirtualDeviceContextStatusChoices
choices=VirtualDeviceContextStatusChoices,
distinct=False,
)
has_primary_ip = django_filters.BooleanFilter(
method='_has_primary_ip',
@@ -1614,6 +1631,7 @@ class ModuleFilterSet(PrimaryModelFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=ModuleStatusChoices,
distinct=False,
null_value=None
)
serial = MultiValueCharFilter(
@@ -1759,6 +1777,7 @@ class DeviceComponentFilterSet(OwnerFilterMixin, NetBoxModelFilterSet):
)
device_status = django_filters.MultipleChoiceFilter(
choices=DeviceStatusChoices,
distinct=False,
field_name='device__status',
)
tenant_id = django_filters.ModelMultipleChoiceFilter(
@@ -1835,6 +1854,7 @@ class PathEndpointFilterSet(django_filters.FilterSet):
class ConsolePortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices,
distinct=False,
null_value=None
)
@@ -1849,6 +1869,7 @@ class ConsolePortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSe
class ConsoleServerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=ConsolePortTypeChoices,
distinct=False,
null_value=None
)
@@ -1863,6 +1884,7 @@ class ConsoleServerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFi
class PowerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PowerPortTypeChoices,
distinct=False,
null_value=None
)
@@ -1878,10 +1900,12 @@ class PowerPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet,
class PowerOutletFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet, PathEndpointFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PowerOutletTypeChoices,
distinct=False,
null_value=None
)
feed_leg = django_filters.MultipleChoiceFilter(
choices=PowerOutletFeedLegChoices,
distinct=False,
null_value=None
)
power_port_id = django_filters.ModelMultipleChoiceFilter(
@@ -1891,6 +1915,7 @@ class PowerOutletFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSe
)
status = django_filters.MultipleChoiceFilter(
choices=PowerOutletStatusChoices,
distinct=False,
null_value=None
)
@@ -2019,6 +2044,7 @@ class MACAddressFilterSet(PrimaryModelFilterSet):
class CommonInterfaceFilterSet(django_filters.FilterSet):
mode = django_filters.MultipleChoiceFilter(
choices=InterfaceModeChoices,
distinct=False,
label=_('802.1Q Mode')
)
vlan_id = django_filters.CharFilter(
@@ -2139,7 +2165,8 @@ class InterfaceFilterSet(
)
speed = MultiValueNumberFilter()
duplex = django_filters.MultipleChoiceFilter(
choices=InterfaceDuplexChoices
choices=InterfaceDuplexChoices,
distinct=False,
)
mac_address = MultiValueMACAddressFilter(
field_name='mac_addresses__mac_address',
@@ -2160,20 +2187,25 @@ class InterfaceFilterSet(
)
wwn = MultiValueWWNFilter()
poe_mode = django_filters.MultipleChoiceFilter(
choices=InterfacePoEModeChoices
choices=InterfacePoEModeChoices,
distinct=False,
)
poe_type = django_filters.MultipleChoiceFilter(
choices=InterfacePoETypeChoices
choices=InterfacePoETypeChoices,
distinct=False,
)
type = django_filters.MultipleChoiceFilter(
choices=InterfaceTypeChoices,
distinct=False,
null_value=None
)
rf_role = django_filters.MultipleChoiceFilter(
choices=WirelessRoleChoices
choices=WirelessRoleChoices,
distinct=False,
)
rf_channel = django_filters.MultipleChoiceFilter(
choices=WirelessChannelChoices
choices=WirelessChannelChoices,
distinct=False,
)
vdc_id = django_filters.ModelMultipleChoiceFilter(
field_name='vdcs',
@@ -2261,6 +2293,7 @@ class InterfaceFilterSet(
class FrontPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices,
distinct=False,
null_value=None
)
rear_port_id = django_filters.ModelMultipleChoiceFilter(
@@ -2282,6 +2315,7 @@ class FrontPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet)
class RearPortFilterSet(ModularDeviceComponentFilterSet, CabledObjectFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=PortTypeChoices,
distinct=False,
null_value=None
)
front_port_id = django_filters.ModelMultipleChoiceFilter(
@@ -2375,6 +2409,7 @@ class InventoryItemFilterSet(DeviceComponentFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=InventoryItemStatusChoices,
distinct=False,
null_value=None
)
@@ -2507,16 +2542,20 @@ class CableFilterSet(TenancyFilterSet, PrimaryModelFilterSet):
label=_('Unterminated'),
)
type = django_filters.MultipleChoiceFilter(
choices=CableTypeChoices
choices=CableTypeChoices,
distinct=False,
)
status = django_filters.MultipleChoiceFilter(
choices=LinkStatusChoices
choices=LinkStatusChoices,
distinct=False,
)
profile = django_filters.MultipleChoiceFilter(
choices=CableProfileChoices
choices=CableProfileChoices,
distinct=False,
)
color = django_filters.MultipleChoiceFilter(
choices=ColorChoices
choices=ColorChoices,
distinct=False,
)
device_id = MultiValueNumberFilter(
method='filter_by_termination'
@@ -2783,6 +2822,7 @@ class PowerFeedFilterSet(PrimaryModelFilterSet, CabledObjectFilterSet, PathEndpo
)
status = django_filters.MultipleChoiceFilter(
choices=PowerFeedStatusChoices,
distinct=False,
null_value=None
)

View File

@@ -72,7 +72,8 @@ class WebhookFilterSet(OwnerFilterMixin, NetBoxModelFilterSet):
label=_('Search'),
)
http_method = django_filters.MultipleChoiceFilter(
choices=WebhookHttpMethodChoices
choices=WebhookHttpMethodChoices,
distinct=False,
)
payload_url = MultiValueCharFilter(
lookup_expr='icontains'
@@ -112,7 +113,8 @@ class EventRuleFilterSet(OwnerFilterMixin, NetBoxModelFilterSet):
method='filter_event_type'
)
action_type = django_filters.MultipleChoiceFilter(
choices=EventRuleActionChoices
choices=EventRuleActionChoices,
distinct=False,
)
action_object_type = ContentTypeFilter()
action_object_id = MultiValueNumberFilter()
@@ -143,7 +145,8 @@ class CustomFieldFilterSet(OwnerFilterMixin, ChangeLoggedModelFilterSet):
label=_('Search'),
)
type = django_filters.MultipleChoiceFilter(
choices=CustomFieldTypeChoices
choices=CustomFieldTypeChoices,
distinct=False,
)
object_type_id = django_filters.ModelMultipleChoiceFilter(
queryset=ObjectType.objects.all(),
@@ -512,7 +515,8 @@ class JournalEntryFilterSet(NetBoxModelFilterSet):
label=_('User (name)'),
)
kind = django_filters.MultipleChoiceFilter(
choices=JournalEntryKindChoices
choices=JournalEntryKindChoices,
distinct=False,
)
class Meta:

View File

@@ -406,6 +406,7 @@ class PrefixFilterSet(PrimaryModelFilterSet, ScopedFilterSet, TenancyFilterSet,
)
status = django_filters.MultipleChoiceFilter(
choices=PrefixStatusChoices,
distinct=False,
null_value=None
)
@@ -523,6 +524,7 @@ class IPRangeFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilt
)
status = django_filters.MultipleChoiceFilter(
choices=IPRangeStatusChoices,
distinct=False,
null_value=None
)
parent = MultiValueCharFilter(
@@ -684,10 +686,12 @@ class IPAddressFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFi
)
status = django_filters.MultipleChoiceFilter(
choices=IPAddressStatusChoices,
distinct=False,
null_value=None
)
role = django_filters.MultipleChoiceFilter(
choices=IPAddressRoleChoices
choices=IPAddressRoleChoices,
distinct=False,
)
service_id = django_filters.ModelMultipleChoiceFilter(
field_name='services',
@@ -819,10 +823,12 @@ class IPAddressFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFi
@register_filterset
class FHRPGroupFilterSet(PrimaryModelFilterSet):
protocol = django_filters.MultipleChoiceFilter(
choices=FHRPGroupProtocolChoices
choices=FHRPGroupProtocolChoices,
distinct=False,
)
auth_type = django_filters.MultipleChoiceFilter(
choices=FHRPGroupAuthTypeChoices
choices=FHRPGroupAuthTypeChoices,
distinct=False,
)
related_ip = django_filters.ModelMultipleChoiceFilter(
queryset=IPAddress.objects.all(),
@@ -1036,6 +1042,7 @@ class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
)
status = django_filters.MultipleChoiceFilter(
choices=VLANStatusChoices,
distinct=False,
null_value=None
)
available_at_site = django_filters.ModelChoiceFilter(
@@ -1051,7 +1058,8 @@ class VLANFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
method='get_for_virtualmachine'
)
qinq_role = django_filters.MultipleChoiceFilter(
choices=VLANQinQRoleChoices
choices=VLANQinQRoleChoices,
distinct=False,
)
qinq_svlan_id = django_filters.ModelMultipleChoiceFilter(
queryset=VLAN.objects.all(),

View File

@@ -71,6 +71,7 @@ class ClusterFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ScopedFilterSet,
)
status = django_filters.MultipleChoiceFilter(
choices=ClusterStatusChoices,
distinct=False,
null_value=None
)
@@ -98,10 +99,12 @@ class VirtualMachineFilterSet(
):
status = django_filters.MultipleChoiceFilter(
choices=VirtualMachineStatusChoices,
distinct=False,
null_value=None
)
start_on_boot = django_filters.MultipleChoiceFilter(
choices=VirtualMachineStartOnBootChoices,
distinct=False,
null_value=None
)
cluster_group_id = django_filters.ModelMultipleChoiceFilter(

View File

@@ -38,7 +38,8 @@ class TunnelGroupFilterSet(OrganizationalModelFilterSet, ContactModelFilterSet):
@register_filterset
class TunnelFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
status = django_filters.MultipleChoiceFilter(
choices=TunnelStatusChoices
choices=TunnelStatusChoices,
distinct=False,
)
group_id = django_filters.ModelMultipleChoiceFilter(
queryset=TunnelGroup.objects.all(),
@@ -53,7 +54,8 @@ class TunnelFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilte
label=_('Tunnel group (slug)'),
)
encapsulation = django_filters.MultipleChoiceFilter(
choices=TunnelEncapsulationChoices
choices=TunnelEncapsulationChoices,
distinct=False,
)
ipsec_profile_id = django_filters.ModelMultipleChoiceFilter(
queryset=IPSecProfile.objects.all(),
@@ -98,7 +100,8 @@ class TunnelTerminationFilterSet(NetBoxModelFilterSet):
label=_('Tunnel (name)'),
)
role = django_filters.MultipleChoiceFilter(
choices=TunnelTerminationRoleChoices
choices=TunnelTerminationRoleChoices,
distinct=False,
)
termination_type = ContentTypeFilter()
interface = django_filters.ModelMultipleChoiceFilter(
@@ -149,16 +152,20 @@ class IKEProposalFilterSet(PrimaryModelFilterSet):
label=_('IKE policy (name)'),
)
authentication_method = django_filters.MultipleChoiceFilter(
choices=AuthenticationMethodChoices
choices=AuthenticationMethodChoices,
distinct=False,
)
encryption_algorithm = django_filters.MultipleChoiceFilter(
choices=EncryptionAlgorithmChoices
choices=EncryptionAlgorithmChoices,
distinct=False,
)
authentication_algorithm = django_filters.MultipleChoiceFilter(
choices=AuthenticationAlgorithmChoices
choices=AuthenticationAlgorithmChoices,
distinct=False,
)
group = django_filters.MultipleChoiceFilter(
choices=DHGroupChoices
choices=DHGroupChoices,
distinct=False,
)
class Meta:
@@ -178,10 +185,12 @@ class IKEProposalFilterSet(PrimaryModelFilterSet):
@register_filterset
class IKEPolicyFilterSet(PrimaryModelFilterSet):
version = django_filters.MultipleChoiceFilter(
choices=IKEVersionChoices
choices=IKEVersionChoices,
distinct=False,
)
mode = django_filters.MultipleChoiceFilter(
choices=IKEModeChoices
choices=IKEModeChoices,
distinct=False,
)
ike_proposal_id = django_filters.ModelMultipleChoiceFilter(
field_name='proposals',
@@ -221,10 +230,12 @@ class IPSecProposalFilterSet(PrimaryModelFilterSet):
label=_('IPSec policy (name)'),
)
encryption_algorithm = django_filters.MultipleChoiceFilter(
choices=EncryptionAlgorithmChoices
choices=EncryptionAlgorithmChoices,
distinct=False,
)
authentication_algorithm = django_filters.MultipleChoiceFilter(
choices=AuthenticationAlgorithmChoices
choices=AuthenticationAlgorithmChoices,
distinct=False,
)
class Meta:
@@ -244,7 +255,8 @@ class IPSecProposalFilterSet(PrimaryModelFilterSet):
@register_filterset
class IPSecPolicyFilterSet(PrimaryModelFilterSet):
pfs_group = django_filters.MultipleChoiceFilter(
choices=DHGroupChoices
choices=DHGroupChoices,
distinct=False,
)
ipsec_proposal_id = django_filters.ModelMultipleChoiceFilter(
field_name='proposals',
@@ -273,7 +285,8 @@ class IPSecPolicyFilterSet(PrimaryModelFilterSet):
@register_filterset
class IPSecProfileFilterSet(PrimaryModelFilterSet):
mode = django_filters.MultipleChoiceFilter(
choices=IPSecModeChoices
choices=IPSecModeChoices,
distinct=False,
)
ike_policy_id = django_filters.ModelMultipleChoiceFilter(
queryset=IKEPolicy.objects.all(),
@@ -318,10 +331,12 @@ class IPSecProfileFilterSet(PrimaryModelFilterSet):
class L2VPNFilterSet(PrimaryModelFilterSet, TenancyFilterSet, ContactModelFilterSet):
type = django_filters.MultipleChoiceFilter(
choices=L2VPNTypeChoices,
distinct=False,
null_value=None
)
status = django_filters.MultipleChoiceFilter(
choices=L2VPNStatusChoices,
distinct=False,
)
import_target_id = django_filters.ModelMultipleChoiceFilter(
field_name='import_targets',

View File

@@ -62,7 +62,8 @@ class WirelessLANFilterSet(PrimaryModelFilterSet, ScopedFilterSet, TenancyFilter
to_field_name='slug'
)
status = django_filters.MultipleChoiceFilter(
choices=WirelessLANStatusChoices
choices=WirelessLANStatusChoices,
distinct=False,
)
vlan_id = django_filters.ModelMultipleChoiceFilter(
queryset=VLAN.objects.all(),
@@ -73,10 +74,12 @@ class WirelessLANFilterSet(PrimaryModelFilterSet, ScopedFilterSet, TenancyFilter
field_name='interfaces'
)
auth_type = django_filters.MultipleChoiceFilter(
choices=WirelessAuthTypeChoices
choices=WirelessAuthTypeChoices,
distinct=False,
)
auth_cipher = django_filters.MultipleChoiceFilter(
choices=WirelessAuthCipherChoices
choices=WirelessAuthCipherChoices,
distinct=False,
)
class Meta:
@@ -104,13 +107,16 @@ class WirelessLinkFilterSet(PrimaryModelFilterSet, TenancyFilterSet):
distinct=False,
)
status = django_filters.MultipleChoiceFilter(
choices=LinkStatusChoices
choices=LinkStatusChoices,
distinct=False,
)
auth_type = django_filters.MultipleChoiceFilter(
choices=WirelessAuthTypeChoices
choices=WirelessAuthTypeChoices,
distinct=False,
)
auth_cipher = django_filters.MultipleChoiceFilter(
choices=WirelessAuthCipherChoices
choices=WirelessAuthCipherChoices,
distinct=False,
)
class Meta: