1
0
mirror of https://github.com/netbox-community/netbox.git synced 2024-05-10 07:54:54 +00:00

Introduce local ChoiceField and MultipleChoiceField classes

This commit is contained in:
jeremystretch
2022-03-21 15:08:05 -04:00
parent ba1e6e91b9
commit 3dc671395e
8 changed files with 108 additions and 114 deletions

View File

@ -35,6 +35,16 @@ In addition to the [form fields provided by Django](https://docs.djangoproject.c
selection:
members: false
## Choice Fields
::: utilities.forms.ChoiceField
selection:
members: false
::: utilities.forms.MultipleChoiceField
selection:
members: false
## Dynamic Object Fields
::: utilities.forms.DynamicModelChoiceField

View File

@ -6,7 +6,7 @@ from circuits.models import *
from dcim.models import Region, Site, SiteGroup
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
from utilities.forms import DynamicModelMultipleChoiceField, StaticSelectMultiple, TagFilterField
from utilities.forms import DynamicModelMultipleChoiceField, MultipleChoiceField, TagFilterField
__all__ = (
'CircuitFilterForm',
@ -101,10 +101,9 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
},
label=_('Provider network')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=CircuitStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),

View File

@ -10,8 +10,8 @@ from ipam.models import ASN, VRF
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms import (
APISelectMultiple, add_blank_choice, ColorField, DynamicModelMultipleChoiceField, FilterForm, StaticSelect,
StaticSelectMultiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, SelectSpeedWidget,
APISelectMultiple, add_blank_choice, ColorField, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField,
StaticSelect, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, SelectSpeedWidget,
)
from wireless.choices import *
@ -140,10 +140,9 @@ class SiteFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
('Tenant', ('tenant_group_id', 'tenant_id')),
('Contacts', ('contact', 'contact_role')),
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=SiteStatusChoices,
required=False,
widget=StaticSelectMultiple(),
required=False
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@ -239,20 +238,17 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
},
label=_('Location')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=RackStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=RackTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
width = forms.MultipleChoiceField(
width = MultipleChoiceField(
choices=RackWidthChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
role_id = DynamicModelMultipleChoiceField(
queryset=RackRole.objects.all(),
@ -346,15 +342,13 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
part_number = forms.CharField(
required=False
)
subdevice_role = forms.MultipleChoiceField(
subdevice_role = MultipleChoiceField(
choices=add_blank_choice(SubdeviceRoleChoices),
required=False,
widget=StaticSelectMultiple()
required=False
)
airflow = forms.MultipleChoiceField(
airflow = MultipleChoiceField(
choices=add_blank_choice(DeviceAirflowChoices),
required=False,
widget=StaticSelectMultiple()
required=False
)
console_ports = forms.NullBooleanField(
required=False,
@ -561,15 +555,13 @@ class DeviceFilterForm(
null_option='None',
label=_('Platform')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=DeviceStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
airflow = forms.MultipleChoiceField(
airflow = MultipleChoiceField(
choices=add_blank_choice(DeviceAirflowChoices),
required=False,
widget=StaticSelectMultiple()
required=False
)
serial = forms.CharField(
required=False
@ -739,15 +731,13 @@ class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
},
label=_('Device')
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=add_blank_choice(CableTypeChoices),
required=False,
widget=StaticSelect()
required=False
)
status = forms.ChoiceField(
status = MultipleChoiceField(
required=False,
choices=add_blank_choice(LinkStatusChoices),
widget=StaticSelect()
choices=add_blank_choice(LinkStatusChoices)
)
color = ColorField(
required=False
@ -843,10 +833,9 @@ class PowerFeedFilterForm(NetBoxModelFilterSetForm):
},
label=_('Rack')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=PowerFeedStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
type = forms.ChoiceField(
choices=add_blank_choice(PowerFeedTypeChoices),
@ -886,15 +875,13 @@ class ConsolePortFilterForm(DeviceComponentFilterForm):
('Attributes', ('name', 'label', 'type', 'speed')),
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=ConsolePortTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
speed = forms.MultipleChoiceField(
speed = MultipleChoiceField(
choices=ConsolePortSpeedChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
tag = TagFilterField(model)
@ -906,15 +893,13 @@ class ConsoleServerPortFilterForm(DeviceComponentFilterForm):
('Attributes', ('name', 'label', 'type', 'speed')),
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=ConsolePortTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
speed = forms.MultipleChoiceField(
speed = MultipleChoiceField(
choices=ConsolePortSpeedChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
tag = TagFilterField(model)
@ -926,10 +911,9 @@ class PowerPortFilterForm(DeviceComponentFilterForm):
('Attributes', ('name', 'label', 'type')),
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=PowerPortTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
tag = TagFilterField(model)
@ -941,10 +925,9 @@ class PowerOutletFilterForm(DeviceComponentFilterForm):
('Attributes', ('name', 'label', 'type')),
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=PowerOutletTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
tag = TagFilterField(model)
@ -958,26 +941,22 @@ class InterfaceFilterForm(DeviceComponentFilterForm):
('Wireless', ('rf_role', 'rf_channel', 'rf_channel_width', 'tx_power')),
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
kind = forms.MultipleChoiceField(
kind = MultipleChoiceField(
choices=InterfaceKindChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=InterfaceTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
speed = forms.IntegerField(
required=False,
label='Select Speed',
widget=SelectSpeedWidget(attrs={'readonly': None})
)
duplex = forms.MultipleChoiceField(
duplex = MultipleChoiceField(
choices=InterfaceDuplexChoices,
required=False,
label='Select Duplex',
widget=StaticSelectMultiple()
required=False
)
enabled = forms.NullBooleanField(
required=False,
@ -999,16 +978,14 @@ class InterfaceFilterForm(DeviceComponentFilterForm):
required=False,
label='WWN'
)
rf_role = forms.MultipleChoiceField(
rf_role = MultipleChoiceField(
choices=WirelessRoleChoices,
required=False,
widget=StaticSelectMultiple(),
label='Wireless role'
)
rf_channel = forms.MultipleChoiceField(
rf_channel = MultipleChoiceField(
choices=WirelessChannelChoices,
required=False,
widget=StaticSelectMultiple(),
label='Wireless channel'
)
rf_channel_frequency = forms.IntegerField(
@ -1040,10 +1017,9 @@ class FrontPortFilterForm(DeviceComponentFilterForm):
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
model = FrontPort
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=PortTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
color = ColorField(
required=False
@ -1058,10 +1034,9 @@ class RearPortFilterForm(DeviceComponentFilterForm):
('Attributes', ('name', 'label', 'type', 'color')),
('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'virtual_chassis_id', 'device_id')),
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=PortTypeChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
color = ColorField(
required=False

View File

@ -10,7 +10,7 @@ from extras.utils import FeatureQuery
from tenancy.models import Tenant, TenantGroup
from utilities.forms import (
add_blank_choice, APISelectMultiple, ContentTypeChoiceField, ContentTypeMultipleChoiceField, DateTimePicker,
DynamicModelMultipleChoiceField, FilterForm, StaticSelect, StaticSelectMultiple, BOOLEAN_WITH_BLANK_CHOICES,
DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField, StaticSelect, BOOLEAN_WITH_BLANK_CHOICES,
)
from virtualization.models import Cluster, ClusterGroup, ClusterType
@ -37,10 +37,9 @@ class CustomFieldFilterForm(FilterForm):
limit_choices_to=FeatureQuery('custom_fields'),
required=False
)
type = forms.MultipleChoiceField(
type = MultipleChoiceField(
choices=CustomFieldTypeChoices,
required=False,
widget=StaticSelectMultiple(),
label=_('Field type')
)
weight = forms.IntegerField(
@ -117,10 +116,9 @@ class WebhookFilterForm(FilterForm):
limit_choices_to=FeatureQuery('webhooks'),
required=False
)
http_method = forms.MultipleChoiceField(
http_method = MultipleChoiceField(
choices=WebhookHttpMethodChoices,
required=False,
widget=StaticSelectMultiple(),
label=_('HTTP method')
)
enabled = forms.NullBooleanField(

View File

@ -9,7 +9,7 @@ from ipam.models import ASN
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import TenancyFilterForm
from utilities.forms import (
add_blank_choice, DynamicModelChoiceField, DynamicModelMultipleChoiceField, StaticSelect, StaticSelectMultiple,
add_blank_choice, DynamicModelChoiceField, DynamicModelMultipleChoiceField, MultipleChoiceField, StaticSelect,
TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
)
@ -164,11 +164,10 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Address family'),
widget=StaticSelect()
)
mask_length = forms.MultipleChoiceField(
mask_length = MultipleChoiceField(
required=False,
choices=PREFIX_MASK_LENGTH_CHOICES,
label=_('Mask length'),
widget=StaticSelectMultiple()
label=_('Mask length')
)
vrf_id = DynamicModelMultipleChoiceField(
queryset=VRF.objects.all(),
@ -181,10 +180,9 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
required=False,
label=_('Present in VRF')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=PrefixStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
region_id = DynamicModelMultipleChoiceField(
queryset=Region.objects.all(),
@ -247,10 +245,9 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
label=_('Assigned VRF'),
null_option='Global'
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=PrefixStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
role_id = DynamicModelMultipleChoiceField(
queryset=Role.objects.all(),
@ -301,15 +298,13 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
required=False,
label=_('Present in VRF')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=IPAddressStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
role = forms.MultipleChoiceField(
role = MultipleChoiceField(
choices=IPAddressRoleChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
assigned_to_interface = forms.NullBooleanField(
required=False,
@ -328,20 +323,18 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
('Attributes', ('protocol', 'group_id')),
('Authentication', ('auth_type', 'auth_key')),
)
protocol = forms.MultipleChoiceField(
protocol = MultipleChoiceField(
choices=FHRPGroupProtocolChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
group_id = forms.IntegerField(
min_value=0,
required=False,
label='Group ID'
)
auth_type = forms.MultipleChoiceField(
auth_type = MultipleChoiceField(
choices=FHRPGroupAuthTypeChoices,
required=False,
widget=StaticSelectMultiple(),
label='Authentication type'
)
auth_key = forms.CharField(
@ -430,10 +423,9 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
},
label=_('VLAN group')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=VLANStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
role_id = DynamicModelMultipleChoiceField(
queryset=Role.objects.all(),
@ -457,7 +449,7 @@ class ServiceTemplateFilterForm(NetBoxModelFilterSetForm):
protocol = forms.ChoiceField(
choices=add_blank_choice(ServiceProtocolChoices),
required=False,
widget=StaticSelectMultiple()
widget=StaticSelect()
)
port = forms.IntegerField(
required=False,

View File

@ -9,11 +9,13 @@ from utilities.forms import widgets
from utilities.validators import EnhancedURLValidator
__all__ = (
'ChoiceField',
'ColorField',
'CommentField',
'JSONField',
'LaxURLField',
'MACAddressField',
'MultipleChoiceField',
'SlugField',
'TagFilterField',
)
@ -125,3 +127,21 @@ class MACAddressField(forms.Field):
raise forms.ValidationError(self.error_messages['invalid'], code='invalid')
return value
#
# Choice fields
#
class ChoiceField(forms.ChoiceField):
"""
Overrides Django's built-in `ChoiceField` to use NetBox's `StaticSelect` widget
"""
widget = widgets.StaticSelect
class MultipleChoiceField(forms.MultipleChoiceField):
"""
Overrides Django's built-in `MultipleChoiceField` to use NetBox's `StaticSelectMultiple` widget
"""
widget = widgets.StaticSelectMultiple

View File

@ -88,9 +88,10 @@ class StaticSelect(forms.Select):
class StaticSelectMultiple(StaticSelect, forms.SelectMultiple):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
"""
Extends `StaticSelect` to support multiple selections.
"""
pass
class SelectWithPK(StaticSelect):

View File

@ -7,7 +7,7 @@ from ipam.models import VRF
from netbox.forms import NetBoxModelFilterSetForm
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms import (
DynamicModelMultipleChoiceField, StaticSelect, StaticSelectMultiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
DynamicModelMultipleChoiceField, MultipleChoiceField, StaticSelect, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
)
from virtualization.choices import *
from virtualization.models import *
@ -135,10 +135,9 @@ class VirtualMachineFilterForm(
},
label=_('Role')
)
status = forms.MultipleChoiceField(
status = MultipleChoiceField(
choices=VirtualMachineStatusChoices,
required=False,
widget=StaticSelectMultiple()
required=False
)
platform_id = DynamicModelMultipleChoiceField(
queryset=Platform.objects.all(),