2
0
Эх сурвалжийг харах

Closes #11765: Remove StaticSelect & StaticSelectMultiple (#11767)

* Remove StaticSelect, StaticSelectMultiple form widgets

* Tag custom ChoiceField, MultipleChoiceField classes for removal in v3.6
Jeremy Stretch 3 жил өмнө
parent
commit
b9bd96f0c7

+ 3 - 0
docs/plugins/development/forms.md

@@ -170,6 +170,9 @@ In addition to the [form fields provided by Django](https://docs.djangoproject.c
 
 
 ## Choice Fields
 ## Choice Fields
 
 
+!!! warning "Obsolete Fields"
+    NetBox's custom `ChoiceField` and `MultipleChoiceField` classes are no longer necessary thanks to improvements made to the user interface. Django's native form fields can be used instead. These custom field classes will be removed in NetBox v3.6.
+
 ::: utilities.forms.ChoiceField
 ::: utilities.forms.ChoiceField
     options:
     options:
       members: false
       members: false

+ 2 - 3
netbox/circuits/forms/bulk_edit.py

@@ -7,7 +7,7 @@ from ipam.models import ASN
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
-    add_blank_choice, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, StaticSelect,
+    add_blank_choice, CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -100,8 +100,7 @@ class CircuitBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(CircuitStatusChoices),
         choices=add_blank_choice(CircuitStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),

+ 2 - 2
netbox/circuits/forms/filtersets.py

@@ -7,7 +7,7 @@ from dcim.models import Region, Site, SiteGroup
 from ipam.models import ASN
 from ipam.models import ASN
 from netbox.forms import NetBoxModelFilterSetForm
 from netbox.forms import NetBoxModelFilterSetForm
 from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
 from tenancy.forms import TenancyFilterForm, ContactModelFilterForm
-from utilities.forms import DatePicker, DynamicModelMultipleChoiceField, MultipleChoiceField, TagFilterField
+from utilities.forms import DatePicker, DynamicModelMultipleChoiceField, TagFilterField
 
 
 __all__ = (
 __all__ = (
     'CircuitFilterForm',
     'CircuitFilterForm',
@@ -107,7 +107,7 @@ class CircuitFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
         },
         },
         label=_('Provider network')
         label=_('Provider network')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=CircuitStatusChoices,
         choices=CircuitStatusChoices,
         required=False
         required=False
     )
     )

+ 0 - 3
netbox/circuits/forms/model_forms.py

@@ -7,7 +7,6 @@ from netbox.forms import NetBoxModelForm
 from tenancy.forms import TenancyForm
 from tenancy.forms import TenancyForm
 from utilities.forms import (
 from utilities.forms import (
     CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SelectSpeedWidget, SlugField,
     CommentField, DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SelectSpeedWidget, SlugField,
-    StaticSelect,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -102,7 +101,6 @@ class CircuitForm(TenancyForm, NetBoxModelForm):
             'commit_rate': _("Committed rate"),
             'commit_rate': _("Committed rate"),
         }
         }
         widgets = {
         widgets = {
-            'status': StaticSelect(),
             'install_date': DatePicker(),
             'install_date': DatePicker(),
             'termination_date': DatePicker(),
             'termination_date': DatePicker(),
             'commit_rate': SelectSpeedWidget(),
             'commit_rate': SelectSpeedWidget(),
@@ -174,7 +172,6 @@ class CircuitTerminationForm(NetBoxModelForm):
             'pp_info': _("Patch panel ID and port number(s)")
             'pp_info': _("Patch panel ID and port number(s)")
         }
         }
         widgets = {
         widgets = {
-            'term_side': StaticSelect(),
             'port_speed': SelectSpeedWidget(),
             'port_speed': SelectSpeedWidget(),
             'upstream_speed': SelectSpeedWidget(),
             'upstream_speed': SelectSpeedWidget(),
         }
         }

+ 2 - 5
netbox/core/forms/bulk_edit.py

@@ -4,9 +4,7 @@ from django.utils.translation import gettext as _
 from core.choices import DataSourceTypeChoices
 from core.choices import DataSourceTypeChoices
 from core.models import *
 from core.models import *
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
-from utilities.forms import (
-    add_blank_choice, BulkEditNullBooleanSelect, CommentField, StaticSelect,
-)
+from utilities.forms import add_blank_choice, BulkEditNullBooleanSelect, CommentField
 
 
 __all__ = (
 __all__ = (
     'DataSourceBulkEditForm',
     'DataSourceBulkEditForm',
@@ -17,8 +15,7 @@ class DataSourceBulkEditForm(NetBoxModelBulkEditForm):
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(DataSourceTypeChoices),
         choices=add_blank_choice(DataSourceTypeChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,

+ 4 - 6
netbox/core/forms/filtersets.py

@@ -4,9 +4,7 @@ from django.utils.translation import gettext as _
 from core.choices import *
 from core.choices import *
 from core.models import *
 from core.models import *
 from netbox.forms import NetBoxModelFilterSetForm
 from netbox.forms import NetBoxModelFilterSetForm
-from utilities.forms import (
-    BOOLEAN_WITH_BLANK_CHOICES, DynamicModelMultipleChoiceField, MultipleChoiceField, StaticSelect,
-)
+from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, DynamicModelMultipleChoiceField
 
 
 __all__ = (
 __all__ = (
     'DataFileFilterForm',
     'DataFileFilterForm',
@@ -20,17 +18,17 @@ class DataSourceFilterForm(NetBoxModelFilterSetForm):
         (None, ('q', 'filter_id')),
         (None, ('q', 'filter_id')),
         ('Data Source', ('type', 'status')),
         ('Data Source', ('type', 'status')),
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=DataSourceTypeChoices,
         choices=DataSourceTypeChoices,
         required=False
         required=False
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=DataSourceStatusChoices,
         choices=DataSourceStatusChoices,
         required=False
         required=False
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )

+ 2 - 2
netbox/core/forms/model_forms.py

@@ -3,7 +3,7 @@ import copy
 from django import forms
 from django import forms
 
 
 from core.models import *
 from core.models import *
-from netbox.forms import NetBoxModelForm, StaticSelect
+from netbox.forms import NetBoxModelForm
 from netbox.registry import registry
 from netbox.registry import registry
 from utilities.forms import CommentField
 from utilities.forms import CommentField
 
 
@@ -21,7 +21,7 @@ class DataSourceForm(NetBoxModelForm):
             'name', 'type', 'source_url', 'enabled', 'description', 'comments', 'ignore_rules', 'tags',
             'name', 'type', 'source_url', 'enabled', 'description', 'comments', 'ignore_rules', 'tags',
         ]
         ]
         widgets = {
         widgets = {
-            'type': StaticSelect(
+            'type': forms.Select(
                 attrs={
                 attrs={
                     'hx-get': '.',
                     'hx-get': '.',
                     'hx-include': '#form_fields input',
                     'hx-include': '#form_fields input',

+ 32 - 68
netbox/dcim/forms/bulk_edit.py

@@ -11,7 +11,7 @@ from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, CommentField, DynamicModelChoiceField,
     add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, CommentField, DynamicModelChoiceField,
-    DynamicModelMultipleChoiceField, form_from_model, StaticSelect, SelectSpeedWidget,
+    DynamicModelMultipleChoiceField, form_from_model, SelectSpeedWidget,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -96,8 +96,7 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(SiteStatusChoices),
         choices=add_blank_choice(SiteStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     region = DynamicModelChoiceField(
     region = DynamicModelChoiceField(
         queryset=Region.objects.all(),
         queryset=Region.objects.all(),
@@ -130,8 +129,7 @@ class SiteBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     time_zone = TimeZoneFormField(
     time_zone = TimeZoneFormField(
         choices=add_blank_choice(TimeZoneFormField().choices),
         choices=add_blank_choice(TimeZoneFormField().choices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         max_length=200,
         max_length=200,
@@ -166,8 +164,7 @@ class LocationBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(LocationStatusChoices),
         choices=add_blank_choice(LocationStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),
@@ -238,8 +235,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(RackStatusChoices),
         choices=add_blank_choice(RackStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     role = DynamicModelChoiceField(
     role = DynamicModelChoiceField(
         queryset=RackRole.objects.all(),
         queryset=RackRole.objects.all(),
@@ -256,13 +252,11 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(RackTypeChoices),
         choices=add_blank_choice(RackTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     width = forms.ChoiceField(
     width = forms.ChoiceField(
         choices=add_blank_choice(RackWidthChoices),
         choices=add_blank_choice(RackWidthChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     u_height = forms.IntegerField(
     u_height = forms.IntegerField(
         required=False,
         required=False,
@@ -283,8 +277,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     outer_unit = forms.ChoiceField(
     outer_unit = forms.ChoiceField(
         choices=add_blank_choice(RackDimensionUnitChoices),
         choices=add_blank_choice(RackDimensionUnitChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     mounting_depth = forms.IntegerField(
     mounting_depth = forms.IntegerField(
         required=False,
         required=False,
@@ -301,8 +294,7 @@ class RackBulkEditForm(NetBoxModelBulkEditForm):
     weight_unit = forms.ChoiceField(
     weight_unit = forms.ChoiceField(
         choices=add_blank_choice(WeightUnitChoices),
         choices=add_blank_choice(WeightUnitChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         max_length=200,
         max_length=200,
@@ -333,8 +325,7 @@ class RackReservationBulkEditForm(NetBoxModelBulkEditForm):
         queryset=User.objects.order_by(
         queryset=User.objects.order_by(
             'username'
             'username'
         ),
         ),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),
@@ -392,8 +383,7 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     airflow = forms.ChoiceField(
     airflow = forms.ChoiceField(
         choices=add_blank_choice(DeviceAirflowChoices),
         choices=add_blank_choice(DeviceAirflowChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     weight = forms.DecimalField(
     weight = forms.DecimalField(
         min_value=0,
         min_value=0,
@@ -402,8 +392,7 @@ class DeviceTypeBulkEditForm(NetBoxModelBulkEditForm):
     weight_unit = forms.ChoiceField(
     weight_unit = forms.ChoiceField(
         choices=add_blank_choice(WeightUnitChoices),
         choices=add_blank_choice(WeightUnitChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         max_length=200,
         max_length=200,
@@ -437,8 +426,7 @@ class ModuleTypeBulkEditForm(NetBoxModelBulkEditForm):
     weight_unit = forms.ChoiceField(
     weight_unit = forms.ChoiceField(
         choices=add_blank_choice(WeightUnitChoices),
         choices=add_blank_choice(WeightUnitChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         max_length=200,
         max_length=200,
@@ -537,13 +525,11 @@ class DeviceBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(DeviceStatusChoices),
         choices=add_blank_choice(DeviceStatusChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     airflow = forms.ChoiceField(
     airflow = forms.ChoiceField(
         choices=add_blank_choice(DeviceAirflowChoices),
         choices=add_blank_choice(DeviceAirflowChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     serial = forms.CharField(
     serial = forms.CharField(
         max_length=50,
         max_length=50,
@@ -585,8 +571,7 @@ class ModuleBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(ModuleStatusChoices),
         choices=add_blank_choice(ModuleStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     serial = forms.CharField(
     serial = forms.CharField(
         max_length=50,
         max_length=50,
@@ -613,13 +598,11 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(CableTypeChoices),
         choices=add_blank_choice(CableTypeChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(LinkStatusChoices),
         choices=add_blank_choice(LinkStatusChoices),
         required=False,
         required=False,
-        widget=StaticSelect(),
         initial=''
         initial=''
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
@@ -640,8 +623,7 @@ class CableBulkEditForm(NetBoxModelBulkEditForm):
     length_unit = forms.ChoiceField(
     length_unit = forms.ChoiceField(
         choices=add_blank_choice(CableLengthUnitChoices),
         choices=add_blank_choice(CableLengthUnitChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         max_length=200,
         max_length=200,
@@ -741,26 +723,22 @@ class PowerFeedBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedStatusChoices),
         choices=add_blank_choice(PowerFeedStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedTypeChoices),
         choices=add_blank_choice(PowerFeedTypeChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     supply = forms.ChoiceField(
     supply = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedSupplyChoices),
         choices=add_blank_choice(PowerFeedSupplyChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     phase = forms.ChoiceField(
     phase = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedPhaseChoices),
         choices=add_blank_choice(PowerFeedPhaseChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     voltage = forms.IntegerField(
     voltage = forms.IntegerField(
         required=False
         required=False
@@ -807,8 +785,7 @@ class ConsolePortTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(ConsolePortTypeChoices),
         choices=add_blank_choice(ConsolePortTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
 
 
     nullable_fields = ('label', 'type', 'description')
     nullable_fields = ('label', 'type', 'description')
@@ -825,8 +802,7 @@ class ConsoleServerPortTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(ConsolePortTypeChoices),
         choices=add_blank_choice(ConsolePortTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         required=False
         required=False
@@ -846,8 +822,7 @@ class PowerPortTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PowerPortTypeChoices),
         choices=add_blank_choice(PowerPortTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     maximum_draw = forms.IntegerField(
     maximum_draw = forms.IntegerField(
         min_value=1,
         min_value=1,
@@ -883,8 +858,7 @@ class PowerOutletTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PowerOutletTypeChoices),
         choices=add_blank_choice(PowerOutletTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     power_port = forms.ModelChoiceField(
     power_port = forms.ModelChoiceField(
         queryset=PowerPortTemplate.objects.all(),
         queryset=PowerPortTemplate.objects.all(),
@@ -892,8 +866,7 @@ class PowerOutletTemplateBulkEditForm(BulkEditForm):
     )
     )
     feed_leg = forms.ChoiceField(
     feed_leg = forms.ChoiceField(
         choices=add_blank_choice(PowerOutletFeedLegChoices),
         choices=add_blank_choice(PowerOutletFeedLegChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     description = forms.CharField(
     description = forms.CharField(
         required=False
         required=False
@@ -924,8 +897,7 @@ class InterfaceTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(InterfaceTypeChoices),
         choices=add_blank_choice(InterfaceTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
@@ -943,14 +915,12 @@ class InterfaceTemplateBulkEditForm(BulkEditForm):
         choices=add_blank_choice(InterfacePoEModeChoices),
         choices=add_blank_choice(InterfacePoEModeChoices),
         required=False,
         required=False,
         initial='',
         initial='',
-        widget=StaticSelect(),
         label=_('PoE mode')
         label=_('PoE mode')
     )
     )
     poe_type = forms.ChoiceField(
     poe_type = forms.ChoiceField(
         choices=add_blank_choice(InterfacePoETypeChoices),
         choices=add_blank_choice(InterfacePoETypeChoices),
         required=False,
         required=False,
         initial='',
         initial='',
-        widget=StaticSelect(),
         label=_('PoE type')
         label=_('PoE type')
     )
     )
 
 
@@ -968,8 +938,7 @@ class FrontPortTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PortTypeChoices),
         choices=add_blank_choice(PortTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     color = ColorField(
     color = ColorField(
         required=False
         required=False
@@ -992,8 +961,7 @@ class RearPortTemplateBulkEditForm(BulkEditForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PortTypeChoices),
         choices=add_blank_choice(PortTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     color = ColorField(
     color = ColorField(
         required=False
         required=False
@@ -1208,14 +1176,12 @@ class InterfaceBulkEditForm(
         choices=add_blank_choice(InterfacePoEModeChoices),
         choices=add_blank_choice(InterfacePoEModeChoices),
         required=False,
         required=False,
         initial='',
         initial='',
-        widget=StaticSelect(),
         label=_('PoE mode')
         label=_('PoE mode')
     )
     )
     poe_type = forms.ChoiceField(
     poe_type = forms.ChoiceField(
         choices=add_blank_choice(InterfacePoETypeChoices),
         choices=add_blank_choice(InterfacePoETypeChoices),
         required=False,
         required=False,
         initial='',
         initial='',
-        widget=StaticSelect(),
         label=_('PoE type')
         label=_('PoE type')
     )
     )
     mark_connected = forms.NullBooleanField(
     mark_connected = forms.NullBooleanField(
@@ -1225,8 +1191,7 @@ class InterfaceBulkEditForm(
     mode = forms.ChoiceField(
     mode = forms.ChoiceField(
         choices=add_blank_choice(InterfaceModeChoices),
         choices=add_blank_choice(InterfaceModeChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     vlan_group = DynamicModelChoiceField(
     vlan_group = DynamicModelChoiceField(
         queryset=VLANGroup.objects.all(),
         queryset=VLANGroup.objects.all(),
@@ -1426,8 +1391,7 @@ class VirtualDeviceContextBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(VirtualDeviceContextStatusChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(VirtualDeviceContextStatusChoices)
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),

+ 66 - 69
netbox/dcim/forms/filtersets.py

@@ -10,8 +10,8 @@ from ipam.models import ASN, L2VPN, VRF
 from netbox.forms import NetBoxModelFilterSetForm
 from netbox.forms import NetBoxModelFilterSetForm
 from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
 from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
 from utilities.forms import (
 from utilities.forms import (
-    APISelectMultiple, add_blank_choice, ColorField, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField,
-    StaticSelect, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, SelectSpeedWidget,
+    APISelectMultiple, add_blank_choice, ColorField, DynamicModelMultipleChoiceField, FilterForm,
+    TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, SelectSpeedWidget,
 )
 )
 from wireless.choices import *
 from wireless.choices import *
 
 
@@ -150,7 +150,7 @@ class SiteFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
         ('Tenant', ('tenant_group_id', 'tenant_id')),
         ('Tenant', ('tenant_group_id', 'tenant_id')),
         ('Contacts', ('contact', 'contact_role', 'contact_group')),
         ('Contacts', ('contact', 'contact_role', 'contact_group')),
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=SiteStatusChoices,
         choices=SiteStatusChoices,
         required=False
         required=False
     )
     )
@@ -208,7 +208,7 @@ class LocationFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelF
         },
         },
         label=_('Parent')
         label=_('Parent')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=LocationStatusChoices,
         choices=LocationStatusChoices,
         required=False
         required=False
     )
     )
@@ -258,15 +258,15 @@ class RackFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFilte
         },
         },
         label=_('Location')
         label=_('Location')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=RackStatusChoices,
         choices=RackStatusChoices,
         required=False
         required=False
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=RackTypeChoices,
         choices=RackTypeChoices,
         required=False
         required=False
     )
     )
-    width = MultipleChoiceField(
+    width = forms.MultipleChoiceField(
         choices=RackWidthChoices,
         choices=RackWidthChoices,
         required=False
         required=False
     )
     )
@@ -399,88 +399,88 @@ class DeviceTypeFilterForm(NetBoxModelFilterSetForm):
     part_number = forms.CharField(
     part_number = forms.CharField(
         required=False
         required=False
     )
     )
-    subdevice_role = MultipleChoiceField(
+    subdevice_role = forms.MultipleChoiceField(
         choices=add_blank_choice(SubdeviceRoleChoices),
         choices=add_blank_choice(SubdeviceRoleChoices),
         required=False
         required=False
     )
     )
-    airflow = MultipleChoiceField(
+    airflow = forms.MultipleChoiceField(
         choices=add_blank_choice(DeviceAirflowChoices),
         choices=add_blank_choice(DeviceAirflowChoices),
         required=False
         required=False
     )
     )
     has_front_image = forms.NullBooleanField(
     has_front_image = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has a front image',
         label='Has a front image',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     has_rear_image = forms.NullBooleanField(
     has_rear_image = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has a rear image',
         label='Has a rear image',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     console_ports = forms.NullBooleanField(
     console_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has console ports',
         label='Has console ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     console_server_ports = forms.NullBooleanField(
     console_server_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has console server ports',
         label='Has console server ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     power_ports = forms.NullBooleanField(
     power_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has power ports',
         label='Has power ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     power_outlets = forms.NullBooleanField(
     power_outlets = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has power outlets',
         label='Has power outlets',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     interfaces = forms.NullBooleanField(
     interfaces = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has interfaces',
         label='Has interfaces',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     pass_through_ports = forms.NullBooleanField(
     pass_through_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has pass-through ports',
         label='Has pass-through ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     device_bays = forms.NullBooleanField(
     device_bays = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has device bays',
         label='Has device bays',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     module_bays = forms.NullBooleanField(
     module_bays = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has module bays',
         label='Has module bays',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     inventory_items = forms.NullBooleanField(
     inventory_items = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has inventory items',
         label='Has inventory items',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -517,42 +517,42 @@ class ModuleTypeFilterForm(NetBoxModelFilterSetForm):
     console_ports = forms.NullBooleanField(
     console_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has console ports',
         label='Has console ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     console_server_ports = forms.NullBooleanField(
     console_server_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has console server ports',
         label='Has console server ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     power_ports = forms.NullBooleanField(
     power_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has power ports',
         label='Has power ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     power_outlets = forms.NullBooleanField(
     power_outlets = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has power outlets',
         label='Has power outlets',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     interfaces = forms.NullBooleanField(
     interfaces = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has interfaces',
         label='Has interfaces',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     pass_through_ports = forms.NullBooleanField(
     pass_through_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has pass-through ports',
         label='Has pass-through ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -662,11 +662,11 @@ class DeviceFilterForm(
         null_option='None',
         null_option='None',
         label=_('Platform')
         label=_('Platform')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=DeviceStatusChoices,
         choices=DeviceStatusChoices,
         required=False
         required=False
     )
     )
-    airflow = MultipleChoiceField(
+    airflow = forms.MultipleChoiceField(
         choices=add_blank_choice(DeviceAirflowChoices),
         choices=add_blank_choice(DeviceAirflowChoices),
         required=False
         required=False
     )
     )
@@ -683,56 +683,56 @@ class DeviceFilterForm(
     has_primary_ip = forms.NullBooleanField(
     has_primary_ip = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has a primary IP',
         label='Has a primary IP',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     virtual_chassis_member = forms.NullBooleanField(
     virtual_chassis_member = forms.NullBooleanField(
         required=False,
         required=False,
         label='Virtual chassis member',
         label='Virtual chassis member',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     console_ports = forms.NullBooleanField(
     console_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has console ports',
         label='Has console ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     console_server_ports = forms.NullBooleanField(
     console_server_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has console server ports',
         label='Has console server ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     power_ports = forms.NullBooleanField(
     power_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has power ports',
         label='Has power ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     power_outlets = forms.NullBooleanField(
     power_outlets = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has power outlets',
         label='Has power outlets',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     interfaces = forms.NullBooleanField(
     interfaces = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has interfaces',
         label='Has interfaces',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     pass_through_ports = forms.NullBooleanField(
     pass_through_ports = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has pass-through ports',
         label='Has pass-through ports',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -755,14 +755,14 @@ class VirtualDeviceContextFilterForm(
         label=_('Device'),
         label=_('Device'),
         fetch_trigger='open'
         fetch_trigger='open'
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         required=False,
         required=False,
         choices=add_blank_choice(VirtualDeviceContextStatusChoices)
         choices=add_blank_choice(VirtualDeviceContextStatusChoices)
     )
     )
     has_primary_ip = forms.NullBooleanField(
     has_primary_ip = forms.NullBooleanField(
         required=False,
         required=False,
         label='Has a primary IP',
         label='Has a primary IP',
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -790,7 +790,7 @@ class ModuleFilterForm(LocalConfigContextFilterForm, TenancyFilterForm, NetBoxMo
         label=_('Type'),
         label=_('Type'),
         fetch_trigger='open'
         fetch_trigger='open'
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=ModuleStatusChoices,
         choices=ModuleStatusChoices,
         required=False
         required=False
     )
     )
@@ -883,11 +883,11 @@ class CableFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         },
         },
         label=_('Device')
         label=_('Device')
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=add_blank_choice(CableTypeChoices),
         choices=add_blank_choice(CableTypeChoices),
         required=False
         required=False
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         required=False,
         required=False,
         choices=add_blank_choice(LinkStatusChoices)
         choices=add_blank_choice(LinkStatusChoices)
     )
     )
@@ -985,24 +985,21 @@ class PowerFeedFilterForm(NetBoxModelFilterSetForm):
         },
         },
         label=_('Rack')
         label=_('Rack')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=PowerFeedStatusChoices,
         choices=PowerFeedStatusChoices,
         required=False
         required=False
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedTypeChoices),
         choices=add_blank_choice(PowerFeedTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     supply = forms.ChoiceField(
     supply = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedSupplyChoices),
         choices=add_blank_choice(PowerFeedSupplyChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     phase = forms.ChoiceField(
     phase = forms.ChoiceField(
         choices=add_blank_choice(PowerFeedPhaseChoices),
         choices=add_blank_choice(PowerFeedPhaseChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     voltage = forms.IntegerField(
     voltage = forms.IntegerField(
         required=False
         required=False
@@ -1023,13 +1020,13 @@ class PowerFeedFilterForm(NetBoxModelFilterSetForm):
 class CabledFilterForm(forms.Form):
 class CabledFilterForm(forms.Form):
     cabled = forms.NullBooleanField(
     cabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     occupied = forms.NullBooleanField(
     occupied = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -1038,7 +1035,7 @@ class CabledFilterForm(forms.Form):
 class PathEndpointFilterForm(CabledFilterForm):
 class PathEndpointFilterForm(CabledFilterForm):
     connected = forms.NullBooleanField(
     connected = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -1052,11 +1049,11 @@ class ConsolePortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Connection', ('cabled', 'connected', 'occupied')),
         ('Connection', ('cabled', 'connected', 'occupied')),
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=ConsolePortTypeChoices,
         choices=ConsolePortTypeChoices,
         required=False
         required=False
     )
     )
-    speed = MultipleChoiceField(
+    speed = forms.MultipleChoiceField(
         choices=ConsolePortSpeedChoices,
         choices=ConsolePortSpeedChoices,
         required=False
         required=False
     )
     )
@@ -1071,11 +1068,11 @@ class ConsoleServerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterF
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Connection', ('cabled', 'connected', 'occupied')),
         ('Connection', ('cabled', 'connected', 'occupied')),
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=ConsolePortTypeChoices,
         choices=ConsolePortTypeChoices,
         required=False
         required=False
     )
     )
-    speed = MultipleChoiceField(
+    speed = forms.MultipleChoiceField(
         choices=ConsolePortSpeedChoices,
         choices=ConsolePortSpeedChoices,
         required=False
         required=False
     )
     )
@@ -1090,7 +1087,7 @@ class PowerPortFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Connection', ('cabled', 'connected', 'occupied')),
         ('Connection', ('cabled', 'connected', 'occupied')),
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=PowerPortTypeChoices,
         choices=PowerPortTypeChoices,
         required=False
         required=False
     )
     )
@@ -1105,7 +1102,7 @@ class PowerOutletFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Connection', ('cabled', 'connected', 'occupied')),
         ('Connection', ('cabled', 'connected', 'occupied')),
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=PowerOutletTypeChoices,
         choices=PowerOutletTypeChoices,
         required=False
         required=False
     )
     )
@@ -1132,11 +1129,11 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
         },
         },
         label=_('Virtual Device Context')
         label=_('Virtual Device Context')
     )
     )
-    kind = MultipleChoiceField(
+    kind = forms.MultipleChoiceField(
         choices=InterfaceKindChoices,
         choices=InterfaceKindChoices,
         required=False
         required=False
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=InterfaceTypeChoices,
         choices=InterfaceTypeChoices,
         required=False
         required=False
     )
     )
@@ -1145,19 +1142,19 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
         label='Speed',
         label='Speed',
         widget=SelectSpeedWidget()
         widget=SelectSpeedWidget()
     )
     )
-    duplex = MultipleChoiceField(
+    duplex = forms.MultipleChoiceField(
         choices=InterfaceDuplexChoices,
         choices=InterfaceDuplexChoices,
         required=False
         required=False
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     mgmt_only = forms.NullBooleanField(
     mgmt_only = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -1169,22 +1166,22 @@ class InterfaceFilterForm(PathEndpointFilterForm, DeviceComponentFilterForm):
         required=False,
         required=False,
         label='WWN'
         label='WWN'
     )
     )
-    poe_mode = MultipleChoiceField(
+    poe_mode = forms.MultipleChoiceField(
         choices=InterfacePoEModeChoices,
         choices=InterfacePoEModeChoices,
         required=False,
         required=False,
         label='PoE mode'
         label='PoE mode'
     )
     )
-    poe_type = MultipleChoiceField(
+    poe_type = forms.MultipleChoiceField(
         choices=InterfacePoETypeChoices,
         choices=InterfacePoETypeChoices,
         required=False,
         required=False,
         label='PoE type'
         label='PoE type'
     )
     )
-    rf_role = MultipleChoiceField(
+    rf_role = forms.MultipleChoiceField(
         choices=WirelessRoleChoices,
         choices=WirelessRoleChoices,
         required=False,
         required=False,
         label='Wireless role'
         label='Wireless role'
     )
     )
-    rf_channel = MultipleChoiceField(
+    rf_channel = forms.MultipleChoiceField(
         choices=WirelessChannelChoices,
         choices=WirelessChannelChoices,
         required=False,
         required=False,
         label='Wireless channel'
         label='Wireless channel'
@@ -1224,7 +1221,7 @@ class FrontPortFilterForm(CabledFilterForm, DeviceComponentFilterForm):
         ('Cable', ('cabled', 'occupied')),
         ('Cable', ('cabled', 'occupied')),
     )
     )
     model = FrontPort
     model = FrontPort
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=PortTypeChoices,
         choices=PortTypeChoices,
         required=False
         required=False
     )
     )
@@ -1242,7 +1239,7 @@ class RearPortFilterForm(CabledFilterForm, DeviceComponentFilterForm):
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Device', ('region_id', 'site_group_id', 'site_id', 'location_id', 'rack_id', 'virtual_chassis_id', 'device_id')),
         ('Cable', ('cabled', 'occupied')),
         ('Cable', ('cabled', 'occupied')),
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=PortTypeChoices,
         choices=PortTypeChoices,
         required=False
         required=False
     )
     )
@@ -1301,7 +1298,7 @@ class InventoryItemFilterForm(DeviceComponentFilterForm):
     )
     )
     discovered = forms.NullBooleanField(
     discovered = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )

+ 4 - 101
netbox/dcim/forms/model_forms.py

@@ -13,7 +13,7 @@ from tenancy.forms import TenancyForm
 from utilities.forms import (
 from utilities.forms import (
     APISelect, add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField,
     APISelect, add_blank_choice, BootstrapMixin, ClearableFileInput, CommentField, ContentTypeChoiceField,
     DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SelectWithPK,
     DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField, NumericArrayField, SelectWithPK,
-    SlugField, StaticSelect, SelectSpeedWidget,
+    SlugField, SelectSpeedWidget,
 )
 )
 from virtualization.models import Cluster, ClusterGroup
 from virtualization.models import Cluster, ClusterGroup
 from wireless.models import WirelessLAN, WirelessLANGroup
 from wireless.models import WirelessLAN, WirelessLANGroup
@@ -129,8 +129,7 @@ class SiteForm(TenancyForm, NetBoxModelForm):
     slug = SlugField()
     slug = SlugField()
     time_zone = TimeZoneFormField(
     time_zone = TimeZoneFormField(
         choices=add_blank_choice(TimeZoneFormField().choices),
         choices=add_blank_choice(TimeZoneFormField().choices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     comments = CommentField()
     comments = CommentField()
 
 
@@ -159,8 +158,6 @@ class SiteForm(TenancyForm, NetBoxModelForm):
                     'rows': 3,
                     'rows': 3,
                 }
                 }
             ),
             ),
-            'status': StaticSelect(),
-            'time_zone': StaticSelect(),
         }
         }
         help_texts = {
         help_texts = {
             'name': _("Full name of the site"),
             'name': _("Full name of the site"),
@@ -218,9 +215,6 @@ class LocationForm(TenancyForm, NetBoxModelForm):
             'region', 'site_group', 'site', 'parent', 'name', 'slug', 'status', 'description', 'tenant_group', 'tenant',
             'region', 'site_group', 'site', 'parent', 'name', 'slug', 'status', 'description', 'tenant_group', 'tenant',
             'tags',
             'tags',
         )
         )
-        widgets = {
-            'status': StaticSelect(),
-        }
 
 
 
 
 class RackRoleForm(NetBoxModelForm):
 class RackRoleForm(NetBoxModelForm):
@@ -287,13 +281,6 @@ class RackForm(TenancyForm, NetBoxModelForm):
             'facility_id': _("The unique rack ID assigned by the facility"),
             'facility_id': _("The unique rack ID assigned by the facility"),
             'u_height': _("Height in rack units"),
             'u_height': _("Height in rack units"),
         }
         }
-        widgets = {
-            'status': StaticSelect(),
-            'type': StaticSelect(),
-            'width': StaticSelect(),
-            'outer_unit': StaticSelect(),
-            'weight_unit': StaticSelect(),
-        }
 
 
 
 
 class RackReservationForm(TenancyForm, NetBoxModelForm):
 class RackReservationForm(TenancyForm, NetBoxModelForm):
@@ -340,8 +327,7 @@ class RackReservationForm(TenancyForm, NetBoxModelForm):
     user = forms.ModelChoiceField(
     user = forms.ModelChoiceField(
         queryset=User.objects.order_by(
         queryset=User.objects.order_by(
             'username'
             'username'
-        ),
-        widget=StaticSelect()
+        )
     )
     )
     comments = CommentField()
     comments = CommentField()
 
 
@@ -402,15 +388,12 @@ class DeviceTypeForm(NetBoxModelForm):
             'weight', 'weight_unit', 'front_image', 'rear_image', 'description', 'comments', 'tags', 'default_platform'
             'weight', 'weight_unit', 'front_image', 'rear_image', 'description', 'comments', 'tags', 'default_platform'
         ]
         ]
         widgets = {
         widgets = {
-            'airflow': StaticSelect(),
-            'subdevice_role': StaticSelect(),
             'front_image': ClearableFileInput(attrs={
             'front_image': ClearableFileInput(attrs={
                 'accept': DEVICETYPE_IMAGE_FORMATS
                 'accept': DEVICETYPE_IMAGE_FORMATS
             }),
             }),
             'rear_image': ClearableFileInput(attrs={
             'rear_image': ClearableFileInput(attrs={
                 'accept': DEVICETYPE_IMAGE_FORMATS
                 'accept': DEVICETYPE_IMAGE_FORMATS
             }),
             }),
-            'weight_unit': StaticSelect(),
         }
         }
 
 
 
 
@@ -431,10 +414,6 @@ class ModuleTypeForm(NetBoxModelForm):
             'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description', 'comments', 'tags',
             'manufacturer', 'model', 'part_number', 'weight', 'weight_unit', 'description', 'comments', 'tags',
         ]
         ]
 
 
-        widgets = {
-            'weight_unit': StaticSelect(),
-        }
-
 
 
 class DeviceRoleForm(NetBoxModelForm):
 class DeviceRoleForm(NetBoxModelForm):
     slug = SlugField()
     slug = SlugField()
@@ -601,13 +580,6 @@ class DeviceForm(TenancyForm, NetBoxModelForm):
             'local_context_data': _("Local config context data overwrites all source contexts in the final rendered "
             'local_context_data': _("Local config context data overwrites all source contexts in the final rendered "
                                     "config context"),
                                     "config context"),
         }
         }
-        widgets = {
-            'face': StaticSelect(),
-            'status': StaticSelect(),
-            'airflow': StaticSelect(),
-            'primary_ip4': StaticSelect(),
-            'primary_ip6': StaticSelect(),
-        }
 
 
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         super().__init__(*args, **kwargs)
@@ -741,11 +713,6 @@ class CableForm(TenancyForm, NetBoxModelForm):
             'type', 'status', 'tenant_group', 'tenant', 'label', 'color', 'length', 'length_unit', 'description',
             'type', 'status', 'tenant_group', 'tenant', 'label', 'color', 'length', 'length_unit', 'description',
             'comments', 'tags',
             'comments', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect,
-            'type': StaticSelect,
-            'length_unit': StaticSelect,
-        }
         error_messages = {
         error_messages = {
             'length': {
             'length': {
                 'max_value': 'Maximum length is 32767 (any unit)'
                 'max_value': 'Maximum length is 32767 (any unit)'
@@ -860,12 +827,6 @@ class PowerFeedForm(NetBoxModelForm):
             'mark_connected', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'description', 'comments',
             'mark_connected', 'supply', 'phase', 'voltage', 'amperage', 'max_utilization', 'description', 'comments',
             'tags',
             'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect(),
-            'type': StaticSelect(),
-            'supply': StaticSelect(),
-            'phase': StaticSelect(),
-        }
 
 
 
 
 #
 #
@@ -1029,9 +990,6 @@ class ConsolePortTemplateForm(ModularComponentTemplateForm):
         fields = [
         fields = [
             'device_type', 'module_type', 'name', 'label', 'type', 'description',
             'device_type', 'module_type', 'name', 'label', 'type', 'description',
         ]
         ]
-        widgets = {
-            'type': StaticSelect,
-        }
 
 
 
 
 class ConsoleServerPortTemplateForm(ModularComponentTemplateForm):
 class ConsoleServerPortTemplateForm(ModularComponentTemplateForm):
@@ -1044,9 +1002,6 @@ class ConsoleServerPortTemplateForm(ModularComponentTemplateForm):
         fields = [
         fields = [
             'device_type', 'module_type', 'name', 'label', 'type', 'description',
             'device_type', 'module_type', 'name', 'label', 'type', 'description',
         ]
         ]
-        widgets = {
-            'type': StaticSelect,
-        }
 
 
 
 
 class PowerPortTemplateForm(ModularComponentTemplateForm):
 class PowerPortTemplateForm(ModularComponentTemplateForm):
@@ -1061,9 +1016,6 @@ class PowerPortTemplateForm(ModularComponentTemplateForm):
         fields = [
         fields = [
             'device_type', 'module_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description',
             'device_type', 'module_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class PowerOutletTemplateForm(ModularComponentTemplateForm):
 class PowerOutletTemplateForm(ModularComponentTemplateForm):
@@ -1084,10 +1036,6 @@ class PowerOutletTemplateForm(ModularComponentTemplateForm):
         fields = [
         fields = [
             'device_type', 'module_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
             'device_type', 'module_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-            'feed_leg': StaticSelect(),
-        }
 
 
 
 
 class InterfaceTemplateForm(ModularComponentTemplateForm):
 class InterfaceTemplateForm(ModularComponentTemplateForm):
@@ -1101,11 +1049,6 @@ class InterfaceTemplateForm(ModularComponentTemplateForm):
         fields = [
         fields = [
             'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type',
             'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'enabled', 'description', 'poe_mode', 'poe_type',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-            'poe_mode': StaticSelect(),
-            'poe_type': StaticSelect(),
-        }
 
 
 
 
 class FrontPortTemplateForm(ModularComponentTemplateForm):
 class FrontPortTemplateForm(ModularComponentTemplateForm):
@@ -1131,9 +1074,6 @@ class FrontPortTemplateForm(ModularComponentTemplateForm):
             'device_type', 'module_type', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position',
             'device_type', 'module_type', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position',
             'description',
             'description',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class RearPortTemplateForm(ModularComponentTemplateForm):
 class RearPortTemplateForm(ModularComponentTemplateForm):
@@ -1146,9 +1086,6 @@ class RearPortTemplateForm(ModularComponentTemplateForm):
         fields = [
         fields = [
             'device_type', 'module_type', 'name', 'label', 'type', 'color', 'positions', 'description',
             'device_type', 'module_type', 'name', 'label', 'type', 'color', 'positions', 'description',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class ModuleBayTemplateForm(ComponentTemplateForm):
 class ModuleBayTemplateForm(ComponentTemplateForm):
@@ -1256,10 +1193,6 @@ class ConsolePortForm(ModularDeviceComponentForm):
         fields = [
         fields = [
             'device', 'module', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags',
             'device', 'module', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-            'speed': StaticSelect(),
-        }
 
 
 
 
 class ConsoleServerPortForm(ModularDeviceComponentForm):
 class ConsoleServerPortForm(ModularDeviceComponentForm):
@@ -1275,10 +1208,6 @@ class ConsoleServerPortForm(ModularDeviceComponentForm):
         fields = [
         fields = [
             'device', 'module', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags',
             'device', 'module', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-            'speed': StaticSelect(),
-        }
 
 
 
 
 class PowerPortForm(ModularDeviceComponentForm):
 class PowerPortForm(ModularDeviceComponentForm):
@@ -1296,9 +1225,6 @@ class PowerPortForm(ModularDeviceComponentForm):
             'device', 'module', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'mark_connected',
             'device', 'module', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'mark_connected',
             'description', 'tags',
             'description', 'tags',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class PowerOutletForm(ModularDeviceComponentForm):
 class PowerOutletForm(ModularDeviceComponentForm):
@@ -1323,10 +1249,6 @@ class PowerOutletForm(ModularDeviceComponentForm):
             'device', 'module', 'name', 'label', 'type', 'power_port', 'feed_leg', 'mark_connected', 'description',
             'device', 'module', 'name', 'label', 'type', 'power_port', 'feed_leg', 'mark_connected', 'description',
             'tags',
             'tags',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-            'feed_leg': StaticSelect(),
-        }
 
 
 
 
 class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
 class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
@@ -1431,14 +1353,7 @@ class InterfaceForm(InterfaceCommonForm, ModularDeviceComponentForm):
             'untagged_vlan', 'tagged_vlans', 'vrf', 'tags',
             'untagged_vlan', 'tagged_vlans', 'vrf', 'tags',
         ]
         ]
         widgets = {
         widgets = {
-            'type': StaticSelect(),
             'speed': SelectSpeedWidget(),
             'speed': SelectSpeedWidget(),
-            'poe_mode': StaticSelect(),
-            'poe_type': StaticSelect(),
-            'duplex': StaticSelect(),
-            'mode': StaticSelect(),
-            'rf_role': StaticSelect(),
-            'rf_channel': StaticSelect(),
         }
         }
         labels = {
         labels = {
             'mode': '802.1Q Mode',
             'mode': '802.1Q Mode',
@@ -1471,9 +1386,6 @@ class FrontPortForm(ModularDeviceComponentForm):
             'device', 'module', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'mark_connected',
             'device', 'module', 'name', 'label', 'type', 'color', 'rear_port', 'rear_port_position', 'mark_connected',
             'description', 'tags',
             'description', 'tags',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class RearPortForm(ModularDeviceComponentForm):
 class RearPortForm(ModularDeviceComponentForm):
@@ -1488,9 +1400,6 @@ class RearPortForm(ModularDeviceComponentForm):
         fields = [
         fields = [
             'device', 'module', 'name', 'label', 'type', 'color', 'positions', 'mark_connected', 'description', 'tags',
             'device', 'module', 'name', 'label', 'type', 'color', 'positions', 'mark_connected', 'description', 'tags',
         ]
         ]
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class ModuleBayForm(DeviceComponentForm):
 class ModuleBayForm(DeviceComponentForm):
@@ -1521,8 +1430,7 @@ class PopulateDeviceBayForm(BootstrapMixin, forms.Form):
     installed_device = forms.ModelChoiceField(
     installed_device = forms.ModelChoiceField(
         queryset=Device.objects.all(),
         queryset=Device.objects.all(),
         label=_('Child Device'),
         label=_('Child Device'),
-        help_text=_("Child devices must first be created and assigned to the site/rack of the parent device."),
-        widget=StaticSelect(),
+        help_text=_("Child devices must first be created and assigned to the site/rack of the parent device.")
     )
     )
 
 
     def __init__(self, device_bay, *args, **kwargs):
     def __init__(self, device_bay, *args, **kwargs):
@@ -1771,8 +1679,3 @@ class VirtualDeviceContextForm(TenancyForm, NetBoxModelForm):
             'region', 'site_group', 'site', 'location', 'rack', 'device', 'name', 'status', 'identifier',
             'region', 'site_group', 'site', 'location', 'rack', 'device', 'name', 'status', 'identifier',
             'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant', 'comments', 'tags'
             'primary_ip4', 'primary_ip6', 'tenant_group', 'tenant', 'comments', 'tags'
         ]
         ]
-        widgets = {
-            'status': StaticSelect(),
-            'primary_ip4': StaticSelect(),
-            'primary_ip6': StaticSelect(),
-        }

+ 3 - 5
netbox/extras/forms/bulk_edit.py

@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
 from extras.choices import *
 from extras.choices import *
 from extras.models import *
 from extras.models import *
 from utilities.forms import (
 from utilities.forms import (
-    add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField, StaticSelect,
+    add_blank_choice, BulkEditForm, BulkEditNullBooleanSelect, ColorField,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -41,8 +41,7 @@ class CustomFieldBulkEditForm(BulkEditForm):
         label=_("UI visibility"),
         label=_("UI visibility"),
         choices=add_blank_choice(CustomFieldVisibilityChoices),
         choices=add_blank_choice(CustomFieldVisibilityChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
 
 
     nullable_fields = ('group_name', 'description',)
     nullable_fields = ('group_name', 'description',)
@@ -66,8 +65,7 @@ class CustomLinkBulkEditForm(BulkEditForm):
     )
     )
     button_class = forms.ChoiceField(
     button_class = forms.ChoiceField(
         choices=add_blank_choice(CustomLinkButtonClassChoices),
         choices=add_blank_choice(CustomLinkButtonClassChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
 
 
 
 

+ 19 - 22
netbox/extras/forms/filtersets.py

@@ -12,8 +12,8 @@ from netbox.forms.base import NetBoxModelFilterSetForm
 from tenancy.models import Tenant, TenantGroup
 from tenancy.models import Tenant, TenantGroup
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField,
     add_blank_choice, APISelectMultiple, BOOLEAN_WITH_BLANK_CHOICES, ContentTypeChoiceField,
-    ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm, MultipleChoiceField,
-    StaticSelect, TagFilterField,
+    ContentTypeMultipleChoiceField, DateTimePicker, DynamicModelMultipleChoiceField, FilterForm,
+    TagFilterField,
 )
 )
 from virtualization.models import Cluster, ClusterGroup, ClusterType
 from virtualization.models import Cluster, ClusterGroup, ClusterType
 from .mixins import SavedFiltersMixin
 from .mixins import SavedFiltersMixin
@@ -43,7 +43,7 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
         required=False,
         required=False,
         label=_('Object type')
         label=_('Object type')
     )
     )
-    type = MultipleChoiceField(
+    type = forms.MultipleChoiceField(
         choices=CustomFieldTypeChoices,
         choices=CustomFieldTypeChoices,
         required=False,
         required=False,
         label=_('Field type')
         label=_('Field type')
@@ -56,15 +56,14 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm):
     )
     )
     required = forms.NullBooleanField(
     required = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     ui_visibility = forms.ChoiceField(
     ui_visibility = forms.ChoiceField(
         choices=add_blank_choice(CustomFieldVisibilityChoices),
         choices=add_blank_choice(CustomFieldVisibilityChoices),
         required=False,
         required=False,
-        label=_('UI visibility'),
-        widget=StaticSelect()
+        label=_('UI visibility')
     )
     )
 
 
 
 
@@ -82,7 +81,7 @@ class JobResultFilterForm(SavedFiltersMixin, FilterForm):
         queryset=ContentType.objects.filter(FeatureQuery('job_results').get_query()),
         queryset=ContentType.objects.filter(FeatureQuery('job_results').get_query()),
         required=False,
         required=False,
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=JobResultStatusChoices,
         choices=JobResultStatusChoices,
         required=False
         required=False
     )
     )
@@ -139,13 +138,13 @@ class CustomLinkFilterForm(SavedFiltersMixin, FilterForm):
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     new_window = forms.NullBooleanField(
     new_window = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -186,7 +185,7 @@ class ExportTemplateFilterForm(SavedFiltersMixin, FilterForm):
     )
     )
     as_attachment = forms.NullBooleanField(
     as_attachment = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -203,13 +202,13 @@ class SavedFilterFilterForm(SavedFiltersMixin, FilterForm):
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     shared = forms.NullBooleanField(
     shared = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -229,32 +228,32 @@ class WebhookFilterForm(SavedFiltersMixin, FilterForm):
         required=False,
         required=False,
         label=_('Object type')
         label=_('Object type')
     )
     )
-    http_method = MultipleChoiceField(
+    http_method = forms.MultipleChoiceField(
         choices=WebhookHttpMethodChoices,
         choices=WebhookHttpMethodChoices,
         required=False,
         required=False,
         label=_('HTTP method')
         label=_('HTTP method')
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     type_create = forms.NullBooleanField(
     type_create = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     type_update = forms.NullBooleanField(
     type_update = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     type_delete = forms.NullBooleanField(
     type_delete = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -363,7 +362,7 @@ class LocalConfigContextFilterForm(forms.Form):
     local_context_data = forms.NullBooleanField(
     local_context_data = forms.NullBooleanField(
         required=False,
         required=False,
         label=_('Has local config context data'),
         label=_('Has local config context data'),
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -404,8 +403,7 @@ class JournalEntryFilterForm(NetBoxModelFilterSetForm):
     )
     )
     kind = forms.ChoiceField(
     kind = forms.ChoiceField(
         choices=add_blank_choice(JournalEntryKindChoices),
         choices=add_blank_choice(JournalEntryKindChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     tag = TagFilterField(model)
     tag = TagFilterField(model)
 
 
@@ -429,8 +427,7 @@ class ObjectChangeFilterForm(SavedFiltersMixin, FilterForm):
     )
     )
     action = forms.ChoiceField(
     action = forms.ChoiceField(
         choices=add_blank_choice(ObjectChangeActionChoices),
         choices=add_blank_choice(ObjectChangeActionChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     user_id = DynamicModelMultipleChoiceField(
     user_id = DynamicModelMultipleChoiceField(
         queryset=User.objects.all(),
         queryset=User.objects.all(),

+ 2 - 10
netbox/extras/forms/model_forms.py

@@ -12,7 +12,7 @@ from netbox.forms import NetBoxModelForm
 from tenancy.models import Tenant, TenantGroup
 from tenancy.models import Tenant, TenantGroup
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, ContentTypeMultipleChoiceField,
     add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, ContentTypeMultipleChoiceField,
-    DynamicModelMultipleChoiceField, JSONField, SlugField, StaticSelect,
+    DynamicModelMultipleChoiceField, JSONField, SlugField,
 )
 )
 from virtualization.models import Cluster, ClusterGroup, ClusterType
 from virtualization.models import Cluster, ClusterGroup, ClusterType
 
 
@@ -58,11 +58,6 @@ class CustomFieldForm(BootstrapMixin, forms.ModelForm):
             'type': _("The type of data stored in this field. For object/multi-object fields, select the related object "
             'type': _("The type of data stored in this field. For object/multi-object fields, select the related object "
                       "type below.")
                       "type below.")
         }
         }
-        widgets = {
-            'type': StaticSelect(),
-            'filter_logic': StaticSelect(),
-            'ui_visibility': StaticSelect(),
-        }
 
 
 
 
 class CustomLinkForm(BootstrapMixin, forms.ModelForm):
 class CustomLinkForm(BootstrapMixin, forms.ModelForm):
@@ -80,7 +75,6 @@ class CustomLinkForm(BootstrapMixin, forms.ModelForm):
         model = CustomLink
         model = CustomLink
         fields = '__all__'
         fields = '__all__'
         widgets = {
         widgets = {
-            'button_class': StaticSelect(),
             'link_text': forms.Textarea(attrs={'class': 'font-monospace'}),
             'link_text': forms.Textarea(attrs={'class': 'font-monospace'}),
             'link_url': forms.Textarea(attrs={'class': 'font-monospace'}),
             'link_url': forms.Textarea(attrs={'class': 'font-monospace'}),
         }
         }
@@ -172,7 +166,6 @@ class WebhookForm(BootstrapMixin, forms.ModelForm):
             'type_delete': 'Deletions',
             'type_delete': 'Deletions',
         }
         }
         widgets = {
         widgets = {
-            'http_method': StaticSelect(),
             'additional_headers': forms.Textarea(attrs={'class': 'font-monospace'}),
             'additional_headers': forms.Textarea(attrs={'class': 'font-monospace'}),
             'body_template': forms.Textarea(attrs={'class': 'font-monospace'}),
             'body_template': forms.Textarea(attrs={'class': 'font-monospace'}),
             'conditions': forms.Textarea(attrs={'class': 'font-monospace'}),
             'conditions': forms.Textarea(attrs={'class': 'font-monospace'}),
@@ -288,8 +281,7 @@ class ImageAttachmentForm(BootstrapMixin, forms.ModelForm):
 class JournalEntryForm(NetBoxModelForm):
 class JournalEntryForm(NetBoxModelForm):
     kind = forms.ChoiceField(
     kind = forms.ChoiceField(
         choices=add_blank_choice(JournalEntryKindChoices),
         choices=add_blank_choice(JournalEntryKindChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     comments = CommentField()
     comments = CommentField()
 
 

+ 5 - 10
netbox/extras/models/customfields.py

@@ -1,6 +1,6 @@
+import decimal
 import re
 import re
 from datetime import datetime, date
 from datetime import datetime, date
-import decimal
 
 
 import django_filters
 import django_filters
 from django import forms
 from django import forms
@@ -24,12 +24,11 @@ from utilities.forms.fields import (
     CSVChoiceField, CSVModelChoiceField, CSVModelMultipleChoiceField, CSVMultipleChoiceField, DynamicModelChoiceField,
     CSVChoiceField, CSVModelChoiceField, CSVModelMultipleChoiceField, CSVMultipleChoiceField, DynamicModelChoiceField,
     DynamicModelMultipleChoiceField, JSONField, LaxURLField,
     DynamicModelMultipleChoiceField, JSONField, LaxURLField,
 )
 )
-from utilities.forms.widgets import DatePicker, StaticSelectMultiple, StaticSelect
 from utilities.forms.utils import add_blank_choice
 from utilities.forms.utils import add_blank_choice
+from utilities.forms.widgets import DatePicker
 from utilities.querysets import RestrictedQuerySet
 from utilities.querysets import RestrictedQuerySet
 from utilities.validators import validate_regex
 from utilities.validators import validate_regex
 
 
-
 __all__ = (
 __all__ = (
     'CustomField',
     'CustomField',
     'CustomFieldManager',
     'CustomFieldManager',
@@ -374,7 +373,7 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
                 (False, 'False'),
                 (False, 'False'),
             )
             )
             field = forms.NullBooleanField(
             field = forms.NullBooleanField(
-                required=required, initial=initial, widget=StaticSelect(choices=choices)
+                required=required, initial=initial, widget=forms.Select(choices=choices)
             )
             )
 
 
         # Date
         # Date
@@ -395,14 +394,10 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel):
 
 
             if self.type == CustomFieldTypeChoices.TYPE_SELECT:
             if self.type == CustomFieldTypeChoices.TYPE_SELECT:
                 field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
                 field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
-                field = field_class(
-                    choices=choices, required=required, initial=initial, widget=StaticSelect()
-                )
+                field = field_class(choices=choices, required=required, initial=initial)
             else:
             else:
                 field_class = CSVMultipleChoiceField if for_csv_import else forms.MultipleChoiceField
                 field_class = CSVMultipleChoiceField if for_csv_import else forms.MultipleChoiceField
-                field = field_class(
-                    choices=choices, required=required, initial=initial, widget=StaticSelectMultiple()
-                )
+                field = field_class(choices=choices, required=required, initial=initial)
 
 
         # URL
         # URL
         elif self.type == CustomFieldTypeChoices.TYPE_URL:
         elif self.type == CustomFieldTypeChoices.TYPE_URL:

+ 10 - 19
netbox/ipam/forms/bulk_edit.py

@@ -9,8 +9,8 @@ from ipam.models import ASN
 from netbox.forms import NetBoxModelBulkEditForm
 from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
-    add_blank_choice, BulkEditNullBooleanSelect, CommentField, DynamicModelChoiceField, NumericArrayField,
-    StaticSelect, DynamicModelMultipleChoiceField,
+    add_blank_choice, BulkEditNullBooleanSelect, CommentField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
+    NumericArrayField,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -205,8 +205,7 @@ class PrefixBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(PrefixStatusChoices),
         choices=add_blank_choice(PrefixStatusChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     role = DynamicModelChoiceField(
     role = DynamicModelChoiceField(
         queryset=Role.objects.all(),
         queryset=Role.objects.all(),
@@ -254,8 +253,7 @@ class IPRangeBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(IPRangeStatusChoices),
         choices=add_blank_choice(IPRangeStatusChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     role = DynamicModelChoiceField(
     role = DynamicModelChoiceField(
         queryset=Role.objects.all(),
         queryset=Role.objects.all(),
@@ -296,13 +294,11 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(IPAddressStatusChoices),
         choices=add_blank_choice(IPAddressStatusChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     role = forms.ChoiceField(
     role = forms.ChoiceField(
         choices=add_blank_choice(IPAddressRoleChoices),
         choices=add_blank_choice(IPAddressRoleChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     dns_name = forms.CharField(
     dns_name = forms.CharField(
         max_length=255,
         max_length=255,
@@ -331,8 +327,7 @@ class IPAddressBulkEditForm(NetBoxModelBulkEditForm):
 class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
 class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
     protocol = forms.ChoiceField(
     protocol = forms.ChoiceField(
         choices=add_blank_choice(FHRPGroupProtocolChoices),
         choices=add_blank_choice(FHRPGroupProtocolChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     group_id = forms.IntegerField(
     group_id = forms.IntegerField(
         min_value=0,
         min_value=0,
@@ -342,7 +337,6 @@ class FHRPGroupBulkEditForm(NetBoxModelBulkEditForm):
     auth_type = forms.ChoiceField(
     auth_type = forms.ChoiceField(
         choices=add_blank_choice(FHRPGroupAuthTypeChoices),
         choices=add_blank_choice(FHRPGroupAuthTypeChoices),
         required=False,
         required=False,
-        widget=StaticSelect(),
         label=_('Authentication type')
         label=_('Authentication type')
     )
     )
     auth_key = forms.CharField(
     auth_key = forms.CharField(
@@ -430,8 +424,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(VLANStatusChoices),
         choices=add_blank_choice(VLANStatusChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     role = DynamicModelChoiceField(
     role = DynamicModelChoiceField(
         queryset=Role.objects.all(),
         queryset=Role.objects.all(),
@@ -459,8 +452,7 @@ class VLANBulkEditForm(NetBoxModelBulkEditForm):
 class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
 class ServiceTemplateBulkEditForm(NetBoxModelBulkEditForm):
     protocol = forms.ChoiceField(
     protocol = forms.ChoiceField(
         choices=add_blank_choice(ServiceProtocolChoices),
         choices=add_blank_choice(ServiceProtocolChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     ports = NumericArrayField(
     ports = NumericArrayField(
         base_field=forms.IntegerField(
         base_field=forms.IntegerField(
@@ -492,8 +484,7 @@ class ServiceBulkEditForm(ServiceTemplateBulkEditForm):
 class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
 class L2VPNBulkEditForm(NetBoxModelBulkEditForm):
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(L2VPNTypeChoices),
         choices=add_blank_choice(L2VPNTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),

+ 20 - 27
netbox/ipam/forms/filtersets.py

@@ -10,7 +10,7 @@ from netbox.forms import NetBoxModelFilterSetForm
 from tenancy.forms import TenancyFilterForm
 from tenancy.forms import TenancyFilterForm
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, ContentTypeMultipleChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
     add_blank_choice, ContentTypeMultipleChoiceField, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
-    MultipleChoiceField, StaticSelect, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
+    TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
 )
 )
 from virtualization.models import VirtualMachine
 from virtualization.models import VirtualMachine
 
 
@@ -87,7 +87,7 @@ class RIRFilterForm(NetBoxModelFilterSetForm):
     is_private = forms.NullBooleanField(
     is_private = forms.NullBooleanField(
         required=False,
         required=False,
         label=_('Private'),
         label=_('Private'),
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -104,8 +104,7 @@ class AggregateFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     family = forms.ChoiceField(
     family = forms.ChoiceField(
         required=False,
         required=False,
         choices=add_blank_choice(IPAddressFamilyChoices),
         choices=add_blank_choice(IPAddressFamilyChoices),
-        label=_('Address family'),
-        widget=StaticSelect()
+        label=_('Address family')
     )
     )
     rir_id = DynamicModelMultipleChoiceField(
     rir_id = DynamicModelMultipleChoiceField(
         queryset=RIR.objects.all(),
         queryset=RIR.objects.all(),
@@ -164,10 +163,9 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     family = forms.ChoiceField(
     family = forms.ChoiceField(
         required=False,
         required=False,
         choices=add_blank_choice(IPAddressFamilyChoices),
         choices=add_blank_choice(IPAddressFamilyChoices),
-        label=_('Address family'),
-        widget=StaticSelect()
+        label=_('Address family')
     )
     )
-    mask_length = MultipleChoiceField(
+    mask_length = forms.MultipleChoiceField(
         required=False,
         required=False,
         choices=PREFIX_MASK_LENGTH_CHOICES,
         choices=PREFIX_MASK_LENGTH_CHOICES,
         label=_('Mask length')
         label=_('Mask length')
@@ -183,7 +181,7 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         required=False,
         required=False,
         label=_('Present in VRF')
         label=_('Present in VRF')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=PrefixStatusChoices,
         choices=PrefixStatusChoices,
         required=False
         required=False
     )
     )
@@ -215,14 +213,14 @@ class PrefixFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     is_pool = forms.NullBooleanField(
     is_pool = forms.NullBooleanField(
         required=False,
         required=False,
         label=_('Is a pool'),
         label=_('Is a pool'),
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
     mark_utilized = forms.NullBooleanField(
     mark_utilized = forms.NullBooleanField(
         required=False,
         required=False,
         label=_('Marked as 100% utilized'),
         label=_('Marked as 100% utilized'),
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -239,8 +237,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     family = forms.ChoiceField(
     family = forms.ChoiceField(
         required=False,
         required=False,
         choices=add_blank_choice(IPAddressFamilyChoices),
         choices=add_blank_choice(IPAddressFamilyChoices),
-        label=_('Address family'),
-        widget=StaticSelect()
+        label=_('Address family')
     )
     )
     vrf_id = DynamicModelMultipleChoiceField(
     vrf_id = DynamicModelMultipleChoiceField(
         queryset=VRF.objects.all(),
         queryset=VRF.objects.all(),
@@ -248,7 +245,7 @@ class IPRangeFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         label=_('Assigned VRF'),
         label=_('Assigned VRF'),
         null_option='Global'
         null_option='Global'
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=IPRangeStatusChoices,
         choices=IPRangeStatusChoices,
         required=False
         required=False
     )
     )
@@ -282,14 +279,12 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     family = forms.ChoiceField(
     family = forms.ChoiceField(
         required=False,
         required=False,
         choices=add_blank_choice(IPAddressFamilyChoices),
         choices=add_blank_choice(IPAddressFamilyChoices),
-        label=_('Address family'),
-        widget=StaticSelect()
+        label=_('Address family')
     )
     )
     mask_length = forms.ChoiceField(
     mask_length = forms.ChoiceField(
         required=False,
         required=False,
         choices=IPADDRESS_MASK_LENGTH_CHOICES,
         choices=IPADDRESS_MASK_LENGTH_CHOICES,
-        label=_('Mask length'),
-        widget=StaticSelect()
+        label=_('Mask length')
     )
     )
     vrf_id = DynamicModelMultipleChoiceField(
     vrf_id = DynamicModelMultipleChoiceField(
         queryset=VRF.objects.all(),
         queryset=VRF.objects.all(),
@@ -312,18 +307,18 @@ class IPAddressFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         required=False,
         required=False,
         label=_('Assigned VM'),
         label=_('Assigned VM'),
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=IPAddressStatusChoices,
         choices=IPAddressStatusChoices,
         required=False
         required=False
     )
     )
-    role = MultipleChoiceField(
+    role = forms.MultipleChoiceField(
         choices=IPAddressRoleChoices,
         choices=IPAddressRoleChoices,
         required=False
         required=False
     )
     )
     assigned_to_interface = forms.NullBooleanField(
     assigned_to_interface = forms.NullBooleanField(
         required=False,
         required=False,
         label=_('Assigned to an interface'),
         label=_('Assigned to an interface'),
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -340,7 +335,7 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
     name = forms.CharField(
     name = forms.CharField(
         required=False
         required=False
     )
     )
-    protocol = MultipleChoiceField(
+    protocol = forms.MultipleChoiceField(
         choices=FHRPGroupProtocolChoices,
         choices=FHRPGroupProtocolChoices,
         required=False
         required=False
     )
     )
@@ -349,7 +344,7 @@ class FHRPGroupFilterForm(NetBoxModelFilterSetForm):
         required=False,
         required=False,
         label='Group ID'
         label='Group ID'
     )
     )
-    auth_type = MultipleChoiceField(
+    auth_type = forms.MultipleChoiceField(
         choices=FHRPGroupAuthTypeChoices,
         choices=FHRPGroupAuthTypeChoices,
         required=False,
         required=False,
         label='Authentication type'
         label='Authentication type'
@@ -444,7 +439,7 @@ class VLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
         },
         },
         label=_('VLAN group')
         label=_('VLAN group')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=VLANStatusChoices,
         choices=VLANStatusChoices,
         required=False
         required=False
     )
     )
@@ -474,8 +469,7 @@ class ServiceTemplateFilterForm(NetBoxModelFilterSetForm):
     )
     )
     protocol = forms.ChoiceField(
     protocol = forms.ChoiceField(
         choices=add_blank_choice(ServiceProtocolChoices),
         choices=add_blank_choice(ServiceProtocolChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     port = forms.IntegerField(
     port = forms.IntegerField(
         required=False,
         required=False,
@@ -497,8 +491,7 @@ class L2VPNFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     )
     )
     type = forms.ChoiceField(
     type = forms.ChoiceField(
         choices=add_blank_choice(L2VPNTypeChoices),
         choices=add_blank_choice(L2VPNTypeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     import_target_id = DynamicModelMultipleChoiceField(
     import_target_id = DynamicModelMultipleChoiceField(
         queryset=RouteTarget.objects.all(),
         queryset=RouteTarget.objects.all(),

+ 1 - 37
netbox/ipam/forms/model_forms.py

@@ -13,7 +13,7 @@ from tenancy.forms import TenancyForm
 from utilities.exceptions import PermissionsViolation
 from utilities.exceptions import PermissionsViolation
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField,
     add_blank_choice, BootstrapMixin, CommentField, ContentTypeChoiceField, DatePicker, DynamicModelChoiceField,
-    DynamicModelMultipleChoiceField, NumericArrayField, SlugField, StaticSelect, StaticSelectMultiple,
+    DynamicModelMultipleChoiceField, NumericArrayField, SlugField,
 )
 )
 from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
 from virtualization.models import Cluster, ClusterGroup, VirtualMachine, VMInterface
 
 
@@ -254,9 +254,6 @@ class PrefixForm(TenancyForm, NetBoxModelForm):
             'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'tenant_group', 'tenant',
             'prefix', 'vrf', 'site', 'vlan', 'status', 'role', 'is_pool', 'mark_utilized', 'tenant_group', 'tenant',
             'description', 'comments', 'tags',
             'description', 'comments', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect(),
-        }
 
 
 
 
 class IPRangeForm(TenancyForm, NetBoxModelForm):
 class IPRangeForm(TenancyForm, NetBoxModelForm):
@@ -282,9 +279,6 @@ class IPRangeForm(TenancyForm, NetBoxModelForm):
             'vrf', 'start_address', 'end_address', 'status', 'role', 'tenant_group', 'tenant', 'description',
             'vrf', 'start_address', 'end_address', 'status', 'role', 'tenant_group', 'tenant', 'description',
             'comments', 'tags',
             'comments', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect(),
-        }
 
 
 
 
 class IPAddressForm(TenancyForm, NetBoxModelForm):
 class IPAddressForm(TenancyForm, NetBoxModelForm):
@@ -411,10 +405,6 @@ class IPAddressForm(TenancyForm, NetBoxModelForm):
             'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant', 'description',
             'nat_cluster', 'nat_virtual_machine', 'nat_vrf', 'nat_inside', 'tenant_group', 'tenant', 'description',
             'comments', 'tags',
             'comments', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect(),
-            'role': StaticSelect(),
-        }
 
 
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
 
 
@@ -510,10 +500,6 @@ class IPAddressBulkAddForm(TenancyForm, NetBoxModelForm):
         fields = [
         fields = [
             'address', 'vrf', 'status', 'role', 'dns_name', 'description', 'tenant_group', 'tenant', 'tags',
             'address', 'vrf', 'status', 'role', 'dns_name', 'description', 'tenant_group', 'tenant', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect(),
-            'role': StaticSelect(),
-        }
 
 
 
 
 class IPAddressAssignForm(BootstrapMixin, forms.Form):
 class IPAddressAssignForm(BootstrapMixin, forms.Form):
@@ -559,11 +545,6 @@ class FHRPGroupForm(NetBoxModelForm):
             'protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'ip_vrf', 'ip_address', 'ip_status', 'description',
             'protocol', 'group_id', 'auth_type', 'auth_key', 'name', 'ip_vrf', 'ip_address', 'ip_status', 'description',
             'comments', 'tags',
             'comments', 'tags',
         )
         )
-        widgets = {
-            'protocol': StaticSelect(),
-            'auth_type': StaticSelect(),
-            'ip_status': StaticSelect(),
-        }
 
 
     def save(self, *args, **kwargs):
     def save(self, *args, **kwargs):
         instance = super().save(*args, **kwargs)
         instance = super().save(*args, **kwargs)
@@ -700,9 +681,6 @@ class VLANGroupForm(NetBoxModelForm):
             'name', 'slug', 'description', 'scope_type', 'region', 'sitegroup', 'site', 'location', 'rack',
             'name', 'slug', 'description', 'scope_type', 'region', 'sitegroup', 'site', 'location', 'rack',
             'clustergroup', 'cluster', 'min_vid', 'max_vid', 'tags',
             'clustergroup', 'cluster', 'min_vid', 'max_vid', 'tags',
         ]
         ]
-        widgets = {
-            'scope_type': StaticSelect,
-        }
 
 
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
         instance = kwargs.get('instance')
         instance = kwargs.get('instance')
@@ -740,7 +718,6 @@ class VLANForm(TenancyForm, NetBoxModelForm):
             ('virtualization.cluster', 'Cluster'),
             ('virtualization.cluster', 'Cluster'),
         ),
         ),
         required=False,
         required=False,
-        widget=StaticSelect,
         label=_('Group scope')
         label=_('Group scope')
     )
     )
     group = DynamicModelChoiceField(
     group = DynamicModelChoiceField(
@@ -800,9 +777,6 @@ class VLANForm(TenancyForm, NetBoxModelForm):
             'status': _("Operational status of this VLAN"),
             'status': _("Operational status of this VLAN"),
             'role': _("The primary function of this VLAN"),
             'role': _("The primary function of this VLAN"),
         }
         }
-        widgets = {
-            'status': StaticSelect(),
-        }
 
 
 
 
 class ServiceTemplateForm(NetBoxModelForm):
 class ServiceTemplateForm(NetBoxModelForm):
@@ -824,9 +798,6 @@ class ServiceTemplateForm(NetBoxModelForm):
     class Meta:
     class Meta:
         model = ServiceTemplate
         model = ServiceTemplate
         fields = ('name', 'protocol', 'ports', 'description', 'comments', 'tags')
         fields = ('name', 'protocol', 'ports', 'description', 'comments', 'tags')
-        widgets = {
-            'protocol': StaticSelect(),
-        }
 
 
 
 
 class ServiceForm(NetBoxModelForm):
 class ServiceForm(NetBoxModelForm):
@@ -865,10 +836,6 @@ class ServiceForm(NetBoxModelForm):
             'ipaddresses': _("IP address assignment is optional. If no IPs are selected, the service is assumed to be "
             'ipaddresses': _("IP address assignment is optional. If no IPs are selected, the service is assumed to be "
                              "reachable via all IPs assigned to the device."),
                              "reachable via all IPs assigned to the device."),
         }
         }
-        widgets = {
-            'protocol': StaticSelect(),
-            'ipaddresses': StaticSelectMultiple(),
-        }
 
 
 
 
 class ServiceCreateForm(ServiceForm):
 class ServiceCreateForm(ServiceForm):
@@ -934,9 +901,6 @@ class L2VPNForm(TenancyForm, NetBoxModelForm):
             'name', 'slug', 'type', 'identifier', 'import_targets', 'export_targets', 'tenant', 'description',
             'name', 'slug', 'type', 'identifier', 'import_targets', 'export_targets', 'tenant', 'description',
             'comments', 'tags'
             'comments', 'tags'
         )
         )
-        widgets = {
-            'type': StaticSelect(),
-        }
 
 
 
 
 class L2VPNTerminationForm(NetBoxModelForm):
 class L2VPNTerminationForm(NetBoxModelForm):

+ 3 - 5
netbox/netbox/forms/__init__.py

@@ -5,7 +5,7 @@ from django.utils.translation import gettext as _
 
 
 from netbox.search import LookupTypes
 from netbox.search import LookupTypes
 from netbox.search.backends import search_backend
 from netbox.search.backends import search_backend
-from utilities.forms import BootstrapMixin, StaticSelect, StaticSelectMultiple
+from utilities.forms import BootstrapMixin
 
 
 from .base import *
 from .base import *
 
 
@@ -32,14 +32,12 @@ class SearchForm(BootstrapMixin, forms.Form):
     obj_types = forms.MultipleChoiceField(
     obj_types = forms.MultipleChoiceField(
         choices=[],
         choices=[],
         required=False,
         required=False,
-        label=_('Object type(s)'),
-        widget=StaticSelectMultiple()
+        label=_('Object type(s)')
     )
     )
     lookup = forms.ChoiceField(
     lookup = forms.ChoiceField(
         choices=LOOKUP_CHOICES,
         choices=LOOKUP_CHOICES,
         initial=LookupTypes.PARTIAL,
         initial=LookupTypes.PARTIAL,
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
 
 
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):

+ 3 - 2
netbox/tenancy/forms/filtersets.py

@@ -1,3 +1,4 @@
+from django import forms
 from django.contrib.contenttypes.models import ContentType
 from django.contrib.contenttypes.models import ContentType
 from django.utils.translation import gettext as _
 from django.utils.translation import gettext as _
 
 
@@ -7,7 +8,7 @@ from tenancy.choices import *
 from tenancy.models import *
 from tenancy.models import *
 from tenancy.forms import ContactModelFilterForm
 from tenancy.forms import ContactModelFilterForm
 from utilities.forms.fields import (
 from utilities.forms.fields import (
-    ContentTypeMultipleChoiceField, DynamicModelMultipleChoiceField, MultipleChoiceField, TagFilterField,
+    ContentTypeMultipleChoiceField, DynamicModelMultipleChoiceField, TagFilterField,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -106,7 +107,7 @@ class ContactAssignmentFilterForm(NetBoxModelFilterSetForm):
         required=False,
         required=False,
         label=_('Role')
         label=_('Role')
     )
     )
-    priority = MultipleChoiceField(
+    priority = forms.MultipleChoiceField(
         choices=ContactPriorityChoices,
         choices=ContactPriorityChoices,
         required=False
         required=False
     )
     )

+ 1 - 2
netbox/tenancy/forms/model_forms.py

@@ -3,7 +3,7 @@ from django import forms
 from netbox.forms import NetBoxModelForm
 from netbox.forms import NetBoxModelForm
 from tenancy.models import *
 from tenancy.models import *
 from utilities.forms import (
 from utilities.forms import (
-    BootstrapMixin, CommentField, DynamicModelChoiceField, SlugField, StaticSelect,
+    BootstrapMixin, CommentField, DynamicModelChoiceField, SlugField,
 )
 )
 
 
 __all__ = (
 __all__ = (
@@ -142,5 +142,4 @@ class ContactAssignmentForm(BootstrapMixin, forms.ModelForm):
         widgets = {
         widgets = {
             'content_type': forms.HiddenInput(),
             'content_type': forms.HiddenInput(),
             'object_id': forms.HiddenInput(),
             'object_id': forms.HiddenInput(),
-            'priority': StaticSelect(),
         }
         }

+ 2 - 2
netbox/users/forms.py

@@ -7,7 +7,7 @@ from django.utils.translation import gettext as _
 
 
 from ipam.formfields import IPNetworkFormField
 from ipam.formfields import IPNetworkFormField
 from netbox.preferences import PREFERENCES
 from netbox.preferences import PREFERENCES
-from utilities.forms import BootstrapMixin, DateTimePicker, StaticSelect
+from utilities.forms import BootstrapMixin, DateTimePicker
 from utilities.utils import flatten_dict
 from utilities.utils import flatten_dict
 from .models import Token, UserConfig
 from .models import Token, UserConfig
 
 
@@ -35,7 +35,7 @@ class UserConfigFormMetaclass(forms.models.ModelFormMetaclass):
                 'help_text': mark_safe(help_text),
                 'help_text': mark_safe(help_text),
                 'coerce': preference.coerce,
                 'coerce': preference.coerce,
                 'required': False,
                 'required': False,
-                'widget': StaticSelect,
+                'widget': forms.Select,
             }
             }
             preference_fields[field_name] = forms.TypedChoiceField(**field_kwargs)
             preference_fields[field_name] = forms.TypedChoiceField(**field_kwargs)
         attrs.update(preference_fields)
         attrs.update(preference_fields)

+ 2 - 2
netbox/utilities/forms/fields/content_types.py

@@ -27,11 +27,11 @@ class ContentTypeChoiceField(ContentTypeChoiceMixin, forms.ModelChoiceField):
     """
     """
     Selection field for a single content type.
     Selection field for a single content type.
     """
     """
-    widget = widgets.StaticSelect
+    pass
 
 
 
 
 class ContentTypeMultipleChoiceField(ContentTypeChoiceMixin, forms.ModelMultipleChoiceField):
 class ContentTypeMultipleChoiceField(ContentTypeChoiceMixin, forms.ModelMultipleChoiceField):
     """
     """
     Selection field for one or more content types.
     Selection field for one or more content types.
     """
     """
-    widget = widgets.StaticSelectMultiple
+    pass

+ 7 - 5
netbox/utilities/forms/fields/fields.py

@@ -68,7 +68,6 @@ class TagFilterField(forms.MultipleChoiceField):
 
 
     :param model: The model of the filter
     :param model: The model of the filter
     """
     """
-    widget = widgets.StaticSelectMultiple
 
 
     def __init__(self, model, *args, **kwargs):
     def __init__(self, model, *args, **kwargs):
         def get_choices():
         def get_choices():
@@ -137,13 +136,16 @@ class MACAddressField(forms.Field):
 
 
 class ChoiceField(forms.ChoiceField):
 class ChoiceField(forms.ChoiceField):
     """
     """
-    Overrides Django's built-in `ChoiceField` to use NetBox's `StaticSelect` widget
+    Previously used to override Django's built-in `ChoiceField` to use NetBox's now-obsolete `StaticSelect` widget.
     """
     """
-    widget = widgets.StaticSelect
+    # TODO: Remove in v3.6
+    pass
 
 
 
 
 class MultipleChoiceField(forms.MultipleChoiceField):
 class MultipleChoiceField(forms.MultipleChoiceField):
     """
     """
-    Overrides Django's built-in `MultipleChoiceField` to use NetBox's `StaticSelectMultiple` widget
+    Previously used to override Django's built-in `MultipleChoiceField` to use NetBox's now-obsolete
+    `StaticSelectMultiple` widget.
     """
     """
-    widget = widgets.StaticSelectMultiple
+    # TODO: Remove in v3.6
+    pass

+ 8 - 9
netbox/utilities/forms/forms.py

@@ -9,7 +9,7 @@ from django.utils.translation import gettext as _
 
 
 from utilities.choices import ImportFormatChoices
 from utilities.choices import ImportFormatChoices
 from utilities.forms.utils import parse_csv
 from utilities.forms.utils import parse_csv
-from .widgets import APISelect, APISelectMultiple, ClearableFileInput, StaticSelect
+from .widgets import APISelect, APISelectMultiple, ClearableFileInput
 
 
 __all__ = (
 __all__ = (
     'BootstrapMixin',
     'BootstrapMixin',
@@ -37,27 +37,27 @@ class BootstrapMixin:
         super().__init__(*args, **kwargs)
         super().__init__(*args, **kwargs)
 
 
         exempt_widgets = [
         exempt_widgets = [
-            forms.CheckboxInput,
             forms.FileInput,
             forms.FileInput,
             forms.RadioSelect,
             forms.RadioSelect,
-            forms.Select,
             APISelect,
             APISelect,
             APISelectMultiple,
             APISelectMultiple,
             ClearableFileInput,
             ClearableFileInput,
-            StaticSelect,
         ]
         ]
 
 
         for field_name, field in self.fields.items():
         for field_name, field in self.fields.items():
             css = field.widget.attrs.get('class', '')
             css = field.widget.attrs.get('class', '')
 
 
-            if field.widget.__class__ not in exempt_widgets:
-                field.widget.attrs['class'] = f'{css} form-control'
+            if field.widget.__class__ in exempt_widgets:
+                continue
 
 
             elif isinstance(field.widget, forms.CheckboxInput):
             elif isinstance(field.widget, forms.CheckboxInput):
                 field.widget.attrs['class'] = f'{css} form-check-input'
                 field.widget.attrs['class'] = f'{css} form-check-input'
 
 
             elif isinstance(field.widget, forms.Select):
             elif isinstance(field.widget, forms.Select):
-                field.widget.attrs['class'] = f'{css} form-select'
+                field.widget.attrs['class'] = f'{css} netbox-static-select'
+
+            else:
+                field.widget.attrs['class'] = f'{css} form-control'
 
 
             if field.required and not isinstance(field.widget, forms.FileInput):
             if field.required and not isinstance(field.widget, forms.FileInput):
                 field.widget.attrs['required'] = 'required'
                 field.widget.attrs['required'] = 'required'
@@ -165,8 +165,7 @@ class ImportForm(BootstrapMixin, forms.Form):
     )
     )
     format = forms.ChoiceField(
     format = forms.ChoiceField(
         choices=ImportFormatChoices,
         choices=ImportFormatChoices,
-        initial=ImportFormatChoices.AUTO,
-        widget=StaticSelect()
+        initial=ImportFormatChoices.AUTO
     )
     )
 
 
     data_field = 'data'
     data_field = 'data'

+ 1 - 22
netbox/utilities/forms/widgets.py

@@ -21,8 +21,6 @@ __all__ = (
     'SelectSpeedWidget',
     'SelectSpeedWidget',
     'SelectWithPK',
     'SelectWithPK',
     'SlugWidget',
     'SlugWidget',
-    'StaticSelect',
-    'StaticSelectMultiple',
     'TimePicker',
     'TimePicker',
 )
 )
 
 
@@ -68,26 +66,7 @@ class BulkEditNullBooleanSelect(forms.NullBooleanSelect):
         self.attrs['class'] = 'netbox-static-select'
         self.attrs['class'] = 'netbox-static-select'
 
 
 
 
-class StaticSelect(forms.Select):
-    """
-    A static <select/> form widget which is client-side rendered.
-    """
-    option_template_name = 'widgets/select_option.html'
-
-    def __init__(self, *args, **kwargs):
-        super().__init__(*args, **kwargs)
-
-        self.attrs['class'] = 'netbox-static-select'
-
-
-class StaticSelectMultiple(StaticSelect, forms.SelectMultiple):
-    """
-    Extends `StaticSelect` to support multiple selections.
-    """
-    pass
-
-
-class SelectWithPK(StaticSelect):
+class SelectWithPK(forms.Select):
     """
     """
     Include the primary key of each option in the option label (e.g. "Router7 (4721)").
     Include the primary key of each option in the option label (e.g. "Router7 (4721)").
     """
     """

+ 3 - 6
netbox/virtualization/forms/bulk_edit.py

@@ -9,7 +9,7 @@ from netbox.forms import NetBoxModelBulkEditForm
 from tenancy.models import Tenant
 from tenancy.models import Tenant
 from utilities.forms import (
 from utilities.forms import (
     add_blank_choice, BulkEditNullBooleanSelect, BulkRenameForm, CommentField, DynamicModelChoiceField,
     add_blank_choice, BulkEditNullBooleanSelect, BulkRenameForm, CommentField, DynamicModelChoiceField,
-    DynamicModelMultipleChoiceField, StaticSelect
+    DynamicModelMultipleChoiceField
 )
 )
 from virtualization.choices import *
 from virtualization.choices import *
 from virtualization.models import *
 from virtualization.models import *
@@ -62,8 +62,7 @@ class ClusterBulkEditForm(NetBoxModelBulkEditForm):
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         choices=add_blank_choice(ClusterStatusChoices),
         choices=add_blank_choice(ClusterStatusChoices),
         required=False,
         required=False,
-        initial='',
-        widget=StaticSelect()
+        initial=''
     )
     )
     tenant = DynamicModelChoiceField(
     tenant = DynamicModelChoiceField(
         queryset=Tenant.objects.all(),
         queryset=Tenant.objects.all(),
@@ -109,7 +108,6 @@ class VirtualMachineBulkEditForm(NetBoxModelBulkEditForm):
         choices=add_blank_choice(VirtualMachineStatusChoices),
         choices=add_blank_choice(VirtualMachineStatusChoices),
         required=False,
         required=False,
         initial='',
         initial='',
-        widget=StaticSelect(),
     )
     )
     site = DynamicModelChoiceField(
     site = DynamicModelChoiceField(
         queryset=Site.objects.all(),
         queryset=Site.objects.all(),
@@ -208,8 +206,7 @@ class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm):
     )
     )
     mode = forms.ChoiceField(
     mode = forms.ChoiceField(
         choices=add_blank_choice(InterfaceModeChoices),
         choices=add_blank_choice(InterfaceModeChoices),
-        required=False,
-        widget=StaticSelect()
+        required=False
     )
     )
     vlan_group = DynamicModelChoiceField(
     vlan_group = DynamicModelChoiceField(
         queryset=VLANGroup.objects.all(),
         queryset=VLANGroup.objects.all(),

+ 5 - 5
netbox/virtualization/forms/filtersets.py

@@ -7,7 +7,7 @@ from ipam.models import L2VPN, VRF
 from netbox.forms import NetBoxModelFilterSetForm
 from netbox.forms import NetBoxModelFilterSetForm
 from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
 from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
 from utilities.forms import (
 from utilities.forms import (
-    DynamicModelMultipleChoiceField, MultipleChoiceField, StaticSelect, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
+    DynamicModelMultipleChoiceField, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES,
 )
 )
 from virtualization.choices import *
 from virtualization.choices import *
 from virtualization.models import *
 from virtualization.models import *
@@ -54,7 +54,7 @@ class ClusterFilterForm(TenancyFilterForm, ContactModelFilterForm, NetBoxModelFi
         required=False,
         required=False,
         label=_('Region')
         label=_('Region')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=ClusterStatusChoices,
         choices=ClusterStatusChoices,
         required=False
         required=False
     )
     )
@@ -148,7 +148,7 @@ class VirtualMachineFilterForm(
         },
         },
         label=_('Role')
         label=_('Role')
     )
     )
-    status = MultipleChoiceField(
+    status = forms.MultipleChoiceField(
         choices=VirtualMachineStatusChoices,
         choices=VirtualMachineStatusChoices,
         required=False
         required=False
     )
     )
@@ -165,7 +165,7 @@ class VirtualMachineFilterForm(
     has_primary_ip = forms.NullBooleanField(
     has_primary_ip = forms.NullBooleanField(
         required=False,
         required=False,
         label=_('Has a primary IP'),
         label=_('Has a primary IP'),
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )
@@ -194,7 +194,7 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
     )
     )
     enabled = forms.NullBooleanField(
     enabled = forms.NullBooleanField(
         required=False,
         required=False,
-        widget=StaticSelect(
+        widget=forms.Select(
             choices=BOOLEAN_WITH_BLANK_CHOICES
             choices=BOOLEAN_WITH_BLANK_CHOICES
         )
         )
     )
     )

+ 1 - 12
netbox/virtualization/forms/model_forms.py

@@ -11,7 +11,7 @@ from netbox.forms import NetBoxModelForm
 from tenancy.forms import TenancyForm
 from tenancy.forms import TenancyForm
 from utilities.forms import (
 from utilities.forms import (
     BootstrapMixin, CommentField, ConfirmationForm, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
     BootstrapMixin, CommentField, ConfirmationForm, DynamicModelChoiceField, DynamicModelMultipleChoiceField,
-    JSONField, SlugField, StaticSelect,
+    JSONField, SlugField,
 )
 )
 from virtualization.models import *
 from virtualization.models import *
 
 
@@ -102,9 +102,6 @@ class ClusterForm(TenancyForm, NetBoxModelForm):
             'name', 'type', 'group', 'status', 'tenant', 'region', 'site_group', 'site', 'description', 'comments',
             'name', 'type', 'group', 'status', 'tenant', 'region', 'site_group', 'site', 'description', 'comments',
             'tags',
             'tags',
         )
         )
-        widgets = {
-            'status': StaticSelect(),
-        }
 
 
 
 
 class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
 class ClusterAddDevicesForm(BootstrapMixin, forms.Form):
@@ -244,11 +241,6 @@ class VirtualMachineForm(TenancyForm, NetBoxModelForm):
             'local_context_data': _("Local config context data overwrites all sources contexts in the final rendered "
             'local_context_data': _("Local config context data overwrites all sources contexts in the final rendered "
                                     "config context"),
                                     "config context"),
         }
         }
-        widgets = {
-            "status": StaticSelect(),
-            'primary_ip4': StaticSelect(),
-            'primary_ip6': StaticSelect(),
-        }
 
 
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         super().__init__(*args, **kwargs)
@@ -354,9 +346,6 @@ class VMInterfaceForm(InterfaceCommonForm, NetBoxModelForm):
             'virtual_machine', 'name', 'parent', 'bridge', 'enabled', 'mac_address', 'mtu', 'description', 'mode',
             'virtual_machine', 'name', 'parent', 'bridge', 'enabled', 'mac_address', 'mtu', 'description', 'mode',
             'vlan_group', 'untagged_vlan', 'tagged_vlans', 'vrf', 'tags',
             'vlan_group', 'untagged_vlan', 'tagged_vlans', 'vrf', 'tags',
         ]
         ]
-        widgets = {
-            'mode': StaticSelect()
-        }
         labels = {
         labels = {
             'mode': '802.1Q Mode',
             'mode': '802.1Q Mode',
         }
         }

+ 7 - 13
netbox/wireless/forms/filtersets.py

@@ -4,7 +4,7 @@ from django.utils.translation import gettext as _
 from dcim.choices import LinkStatusChoices
 from dcim.choices import LinkStatusChoices
 from netbox.forms import NetBoxModelFilterSetForm
 from netbox.forms import NetBoxModelFilterSetForm
 from tenancy.forms import TenancyFilterForm
 from tenancy.forms import TenancyFilterForm
-from utilities.forms import add_blank_choice, DynamicModelMultipleChoiceField, StaticSelect, TagFilterField
+from utilities.forms import add_blank_choice, DynamicModelMultipleChoiceField, TagFilterField
 from wireless.choices import *
 from wireless.choices import *
 from wireless.models import *
 from wireless.models import *
 
 
@@ -45,18 +45,15 @@ class WirelessLANFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(WirelessLANStatusChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(WirelessLANStatusChoices)
     )
     )
     auth_type = forms.ChoiceField(
     auth_type = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(WirelessAuthTypeChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(WirelessAuthTypeChoices)
     )
     )
     auth_cipher = forms.ChoiceField(
     auth_cipher = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(WirelessAuthCipherChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(WirelessAuthCipherChoices)
     )
     )
     auth_psk = forms.CharField(
     auth_psk = forms.CharField(
         required=False
         required=False
@@ -78,18 +75,15 @@ class WirelessLinkFilterForm(TenancyFilterForm, NetBoxModelFilterSetForm):
     )
     )
     status = forms.ChoiceField(
     status = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(LinkStatusChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(LinkStatusChoices)
     )
     )
     auth_type = forms.ChoiceField(
     auth_type = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(WirelessAuthTypeChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(WirelessAuthTypeChoices)
     )
     )
     auth_cipher = forms.ChoiceField(
     auth_cipher = forms.ChoiceField(
         required=False,
         required=False,
-        choices=add_blank_choice(WirelessAuthCipherChoices),
-        widget=StaticSelect()
+        choices=add_blank_choice(WirelessAuthCipherChoices)
     )
     )
     auth_psk = forms.CharField(
     auth_psk = forms.CharField(
         required=False
         required=False

+ 1 - 11
netbox/wireless/forms/model_forms.py

@@ -3,7 +3,7 @@ from dcim.models import Device, Interface, Location, Region, Site, SiteGroup
 from ipam.models import VLAN, VLANGroup
 from ipam.models import VLAN, VLANGroup
 from netbox.forms import NetBoxModelForm
 from netbox.forms import NetBoxModelForm
 from tenancy.forms import TenancyForm
 from tenancy.forms import TenancyForm
-from utilities.forms import CommentField, DynamicModelChoiceField, SlugField, StaticSelect
+from utilities.forms import CommentField, DynamicModelChoiceField, SlugField
 from wireless.models import *
 from wireless.models import *
 
 
 __all__ = (
 __all__ = (
@@ -97,11 +97,6 @@ class WirelessLANForm(TenancyForm, NetBoxModelForm):
             'ssid', 'group', 'region', 'site_group', 'site', 'status', 'vlan_group', 'vlan', 'tenant_group', 'tenant',
             'ssid', 'group', 'region', 'site_group', 'site', 'status', 'vlan_group', 'vlan', 'tenant_group', 'tenant',
             'auth_type', 'auth_cipher', 'auth_psk', 'description', 'comments', 'tags',
             'auth_type', 'auth_cipher', 'auth_psk', 'description', 'comments', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect,
-            'auth_type': StaticSelect,
-            'auth_cipher': StaticSelect,
-        }
 
 
 
 
 class WirelessLinkForm(TenancyForm, NetBoxModelForm):
 class WirelessLinkForm(TenancyForm, NetBoxModelForm):
@@ -202,11 +197,6 @@ class WirelessLinkForm(TenancyForm, NetBoxModelForm):
             'status', 'ssid', 'tenant_group', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description',
             'status', 'ssid', 'tenant_group', 'tenant', 'auth_type', 'auth_cipher', 'auth_psk', 'description',
             'comments', 'tags',
             'comments', 'tags',
         ]
         ]
-        widgets = {
-            'status': StaticSelect,
-            'auth_type': StaticSelect,
-            'auth_cipher': StaticSelect,
-        }
         labels = {
         labels = {
             'auth_type': 'Type',
             'auth_type': 'Type',
             'auth_cipher': 'Cipher',
             'auth_cipher': 'Cipher',