diff --git a/netbox/extras/api/serializers.py b/netbox/extras/api/serializers.py index 8b9c6dcb1..01b841a0f 100644 --- a/netbox/extras/api/serializers.py +++ b/netbox/extras/api/serializers.py @@ -97,6 +97,12 @@ class CustomFieldSerializer(ValidatedModelSerializer): 'validation_minimum', 'validation_maximum', 'validation_regex', 'choices', 'created', 'last_updated', ] + def validate_type(self, value): + if self.instance and self.instance.type != value: + raise serializers.ValidationError('Changing the type of custom fields is not supported.') + + return value + def get_data_type(self, obj): types = CustomFieldTypeChoices if obj.type == types.TYPE_INTEGER: diff --git a/netbox/extras/forms/model_forms.py b/netbox/extras/forms/model_forms.py index 040882d27..365d55c72 100644 --- a/netbox/extras/forms/model_forms.py +++ b/netbox/extras/forms/model_forms.py @@ -64,6 +64,13 @@ class CustomFieldForm(BootstrapMixin, forms.ModelForm): 'ui_visibility': StaticSelect(), } + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + # Disable changing the type of a CustomField as it almost universally causes errors if custom field data is already present. + if self.instance.pk: + self.fields['type'].disabled = True + class CustomLinkForm(BootstrapMixin, forms.ModelForm): content_types = ContentTypeMultipleChoiceField( diff --git a/netbox/extras/tests/test_api.py b/netbox/extras/tests/test_api.py index 4b5efda3c..c915d596a 100644 --- a/netbox/extras/tests/test_api.py +++ b/netbox/extras/tests/test_api.py @@ -102,6 +102,11 @@ class CustomFieldTest(APIViewTestCases.APIViewTestCase): bulk_update_data = { 'description': 'New description', } + update_data = { + 'content_types': ['dcim.device'], + 'name': 'New_Name', + 'description': 'New description', + } @classmethod def setUpTestData(cls):