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:
@ -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
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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(),
|
||||
|
Reference in New Issue
Block a user