diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 98b321b90..a126a1ea0 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -23,8 +23,8 @@ from tenancy.models import Tenant, TenantGroup from utilities.forms import ( APISelect, APISelectMultiple, add_blank_choice, ArrayFieldSelectMultiple, BootstrapMixin, BulkEditForm, BulkEditNullBooleanSelect, ColorSelect, CommentField, ConfirmationForm, CSVChoiceField, DynamicModelChoiceField, - DynamicModelMultipleChoiceField, ExpandableNameField, FlexibleModelChoiceField, form_from_model, JSONField, - SelectWithPK, SmallTextarea, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, + DynamicModelMultipleChoiceField, ExpandableNameField, form_from_model, JSONField, SelectWithPK, SmallTextarea, + SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, ) from virtualization.models import Cluster, ClusterGroup, VirtualMachine @@ -2046,10 +2046,10 @@ class DeviceCSVForm(BaseDeviceCSVForm): class ChildDeviceCSVForm(BaseDeviceCSVForm): - parent = FlexibleModelChoiceField( + parent = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of parent device', + help_text='Parent device', error_messages={ 'invalid_choice': 'Parent device not found.', } @@ -2381,10 +2381,9 @@ class ConsolePortBulkEditForm( class ConsolePortCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } @@ -2485,10 +2484,9 @@ class ConsoleServerPortBulkDisconnectForm(ConfirmationForm): class ConsoleServerPortCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } @@ -2585,10 +2583,9 @@ class PowerPortBulkEditForm( class PowerPortCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } @@ -2736,21 +2733,19 @@ class PowerOutletBulkDisconnectForm(ConfirmationForm): class PowerOutletCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } ) - power_port = FlexibleModelChoiceField( + power_port = forms.ModelChoiceField( queryset=PowerPort.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of Power Port', error_messages={ - 'invalid_choice': 'Power Port not found.', + 'invalid_choice': 'Power port not found.', } ) feed_leg = CSVChoiceField( @@ -3058,29 +3053,27 @@ class InterfaceBulkDisconnectForm(ConfirmationForm): class InterfaceCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } ) - virtual_machine = FlexibleModelChoiceField( + virtual_machine = forms.ModelChoiceField( queryset=VirtualMachine.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of virtual machine', error_messages={ 'invalid_choice': 'Virtual machine not found.', } ) - lag = FlexibleModelChoiceField( + lag = forms.ModelChoiceField( queryset=Interface.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of LAG interface', + help_text='LAG interface', error_messages={ 'invalid_choice': 'LAG interface not found.', } @@ -3271,18 +3264,16 @@ class FrontPortBulkDisconnectForm(ConfirmationForm): class FrontPortCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } ) - rear_port = FlexibleModelChoiceField( + rear_port = forms.ModelChoiceField( queryset=RearPort.objects.all(), to_field_name='name', - help_text='Name or ID of Rear Port', error_messages={ 'invalid_choice': 'Rear Port not found.', } @@ -3409,10 +3400,9 @@ class RearPortBulkDisconnectForm(ConfirmationForm): class RearPortCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } @@ -3517,19 +3507,17 @@ class DeviceBayBulkRenameForm(BulkRenameForm): class DeviceBayCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } ) - installed_device = FlexibleModelChoiceField( + installed_device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Child device not found.', } @@ -3811,10 +3799,10 @@ class CableForm(BootstrapMixin, forms.ModelForm): class CableCSVForm(forms.ModelForm): # Termination A - side_a_device = FlexibleModelChoiceField( + side_a_device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Side A device name or ID', + help_text='Side A device', error_messages={ 'invalid_choice': 'Side A device not found', } @@ -3830,10 +3818,10 @@ class CableCSVForm(forms.ModelForm): ) # Termination B - side_b_device = FlexibleModelChoiceField( + side_b_device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Side B device name or ID', + help_text='Side B device', error_messages={ 'invalid_choice': 'Side B device not found', } @@ -4164,10 +4152,9 @@ class InventoryItemCreateForm(BootstrapMixin, forms.Form): class InventoryItemCSVForm(forms.ModelForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Device name or ID', error_messages={ 'invalid_choice': 'Device not found.', } diff --git a/netbox/ipam/forms.py b/netbox/ipam/forms.py index 854843f2e..9a568a2a6 100644 --- a/netbox/ipam/forms.py +++ b/netbox/ipam/forms.py @@ -11,16 +11,14 @@ from tenancy.forms import TenancyFilterForm, TenancyForm from tenancy.models import Tenant from utilities.forms import ( add_blank_choice, APISelect, APISelectMultiple, BootstrapMixin, BulkEditNullBooleanSelect, CSVChoiceField, - DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableIPAddressField, - FlexibleModelChoiceField, ReturnURLForm, SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, - BOOLEAN_WITH_BLANK_CHOICES, + DatePicker, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableIPAddressField, ReturnURLForm, + SlugField, StaticSelect2, StaticSelect2Multiple, TagFilterField, BOOLEAN_WITH_BLANK_CHOICES, ) from virtualization.models import VirtualMachine -from .constants import * from .choices import * +from .constants import * from .models import Aggregate, IPAddress, Prefix, RIR, Role, Service, VLAN, VLANGroup, VRF - PREFIX_MASK_LENGTH_CHOICES = add_blank_choice([ (i, i) for i in range(PREFIX_LENGTH_MIN, PREFIX_LENGTH_MAX + 1) ]) @@ -333,11 +331,10 @@ class PrefixForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): class PrefixCSVForm(CustomFieldModelCSVForm): - vrf = FlexibleModelChoiceField( + vrf = forms.ModelChoiceField( queryset=VRF.objects.all(), to_field_name='name', required=False, - help_text='Name of parent VRF (or {ID})', error_messages={ 'invalid_choice': 'VRF not found.', } @@ -737,11 +734,10 @@ class IPAddressBulkAddForm(BootstrapMixin, TenancyForm, CustomFieldModelForm): class IPAddressCSVForm(CustomFieldModelCSVForm): - vrf = FlexibleModelChoiceField( + vrf = forms.ModelChoiceField( queryset=VRF.objects.all(), to_field_name='name', required=False, - help_text='Name of parent VRF (or {ID})', error_messages={ 'invalid_choice': 'VRF not found.', } @@ -764,11 +760,11 @@ class IPAddressCSVForm(CustomFieldModelCSVForm): required=False, help_text='Functional role' ) - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of assigned device', + help_text='Assigned device', error_messages={ 'invalid_choice': 'Device not found.', } @@ -777,7 +773,7 @@ class IPAddressCSVForm(CustomFieldModelCSVForm): queryset=VirtualMachine.objects.all(), required=False, to_field_name='name', - help_text='Name of assigned virtual machine', + help_text='Assigned virtual machine', error_messages={ 'invalid_choice': 'Virtual machine not found.', } @@ -1299,20 +1295,18 @@ class ServiceFilterForm(BootstrapMixin, CustomFieldFilterForm): class ServiceCSVForm(CustomFieldModelCSVForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of device', error_messages={ 'invalid_choice': 'Device not found.', } ) - virtual_machine = FlexibleModelChoiceField( + virtual_machine = forms.ModelChoiceField( queryset=VirtualMachine.objects.all(), required=False, to_field_name='name', - help_text='Name or ID of virtual machine', error_messages={ 'invalid_choice': 'Virtual machine not found.', } diff --git a/netbox/secrets/forms.py b/netbox/secrets/forms.py index 03ff8fab8..3243687e5 100644 --- a/netbox/secrets/forms.py +++ b/netbox/secrets/forms.py @@ -8,8 +8,8 @@ from extras.forms import ( AddRemoveTagsForm, CustomFieldBulkEditForm, CustomFieldFilterForm, CustomFieldModelForm, CustomFieldModelCSVForm, ) from utilities.forms import ( - APISelect, APISelectMultiple, BootstrapMixin, DynamicModelChoiceField, DynamicModelMultipleChoiceField, - FlexibleModelChoiceField, SlugField, StaticSelect2Multiple, TagFilterField, + APISelectMultiple, BootstrapMixin, DynamicModelChoiceField, DynamicModelMultipleChoiceField, SlugField, + StaticSelect2Multiple, TagFilterField, ) from .constants import * from .models import Secret, SecretRole, UserKey @@ -120,10 +120,9 @@ class SecretForm(BootstrapMixin, CustomFieldModelForm): class SecretCSVForm(CustomFieldModelCSVForm): - device = FlexibleModelChoiceField( + device = forms.ModelChoiceField( queryset=Device.objects.all(), to_field_name='name', - help_text='Device name or ID', error_messages={ 'invalid_choice': 'Device not found.', } diff --git a/netbox/utilities/forms.py b/netbox/utilities/forms.py index 61ab28ec8..351b845ae 100644 --- a/netbox/utilities/forms.py +++ b/netbox/utilities/forms.py @@ -552,27 +552,6 @@ class CommentField(forms.CharField): super().__init__(required=required, label=label, help_text=help_text, *args, **kwargs) -class FlexibleModelChoiceField(forms.ModelChoiceField): - """ - Allow a model to be reference by either '{ID}' or the field specified by `to_field_name`. - """ - def to_python(self, value): - if value in self.empty_values: - return None - try: - if not self.to_field_name: - key = 'pk' - elif re.match(r'^\{\d+\}$', value): - key = 'pk' - value = value.strip('{}') - else: - key = self.to_field_name - value = self.queryset.get(**{key: value}) - except (ValueError, TypeError, self.queryset.model.DoesNotExist): - raise forms.ValidationError(self.error_messages['invalid_choice'], code='invalid_choice') - return value - - class SlugField(forms.SlugField): """ Extend the built-in SlugField to automatically populate from a field called `name` unless otherwise specified.