From 276dd6c94e367b6d5a8154f807419d00144edef9 Mon Sep 17 00:00:00 2001 From: Jathn Date: Fri, 29 Aug 2025 17:49:37 +0300 Subject: [PATCH 1/5] Fixes #19896: allow decimal number boundaries for custom fields --- netbox/extras/forms/filtersets.py | 4 ++-- ...130_update_custom_fields_numeric_bounds.py | 23 +++++++++++++++++++ netbox/extras/models/customfields.py | 8 +++++-- 3 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py diff --git a/netbox/extras/forms/filtersets.py b/netbox/extras/forms/filtersets.py index 27881f17a95..bd502029e35 100644 --- a/netbox/extras/forms/filtersets.py +++ b/netbox/extras/forms/filtersets.py @@ -102,11 +102,11 @@ class CustomFieldFilterForm(SavedFiltersMixin, FilterForm): choices=BOOLEAN_WITH_BLANK_CHOICES ) ) - validation_minimum = forms.IntegerField( + validation_minimum = forms.DecimalField( label=_('Minimum value'), required=False ) - validation_maximum = forms.IntegerField( + validation_maximum = forms.DecimalField( label=_('Maximum value'), required=False ) diff --git a/netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py b/netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py new file mode 100644 index 00000000000..dcc225617dc --- /dev/null +++ b/netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py @@ -0,0 +1,23 @@ +# Generated by Django 5.2.4 on 2025-08-28 19:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0129_fix_script_paths'), + ] + + operations = [ + migrations.AlterField( + model_name='customfield', + name='validation_maximum', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=21, null=True), + ), + migrations.AlterField( + model_name='customfield', + name='validation_minimum', + field=models.DecimalField(blank=True, decimal_places=2, max_digits=21, null=True), + ), + ] diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 19d9e1ded0a..78b30e9ab57 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -174,13 +174,17 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): verbose_name=_('display weight'), help_text=_('Fields with higher weights appear lower in a form.') ) - validation_minimum = models.BigIntegerField( + validation_minimum = models.DecimalField( + max_digits=21, + decimal_places=2, blank=True, null=True, verbose_name=_('minimum value'), help_text=_('Minimum allowed value (for numeric fields)') ) - validation_maximum = models.BigIntegerField( + validation_maximum = models.DecimalField( + max_digits=21, + decimal_places=2, blank=True, null=True, verbose_name=_('maximum value'), From 6cc6650b32be163f70dec22dc869040eadbeac1b Mon Sep 17 00:00:00 2001 From: Jathn Date: Thu, 4 Sep 2025 14:08:48 +0300 Subject: [PATCH 2/5] Change max_digits and decimal_places to match Integer instead of BigInteger --- netbox/extras/forms/bulk_edit.py | 4 ++-- ...0_alter_customfield_validation_maximum_and_more.py} | 6 +++--- netbox/extras/models/customfields.py | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) rename netbox/extras/migrations/{0130_update_custom_fields_numeric_bounds.py => 0130_alter_customfield_validation_maximum_and_more.py} (83%) diff --git a/netbox/extras/forms/bulk_edit.py b/netbox/extras/forms/bulk_edit.py index c854a6c8103..ebadae8f490 100644 --- a/netbox/extras/forms/bulk_edit.py +++ b/netbox/extras/forms/bulk_edit.py @@ -73,11 +73,11 @@ class CustomFieldBulkEditForm(BulkEditForm): required=False, widget=BulkEditNullBooleanSelect() ) - validation_minimum = forms.IntegerField( + validation_minimum = forms.DecimalField( label=_('Minimum value'), required=False, ) - validation_maximum = forms.IntegerField( + validation_maximum = forms.DecimalField( label=_('Maximum value'), required=False, ) diff --git a/netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py b/netbox/extras/migrations/0130_alter_customfield_validation_maximum_and_more.py similarity index 83% rename from netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py rename to netbox/extras/migrations/0130_alter_customfield_validation_maximum_and_more.py index dcc225617dc..35f9a92a828 100644 --- a/netbox/extras/migrations/0130_update_custom_fields_numeric_bounds.py +++ b/netbox/extras/migrations/0130_alter_customfield_validation_maximum_and_more.py @@ -1,4 +1,4 @@ -# Generated by Django 5.2.4 on 2025-08-28 19:31 +# Generated by Django 5.2.4 on 2025-09-04 10:50 from django.db import migrations, models @@ -13,11 +13,11 @@ class Migration(migrations.Migration): migrations.AlterField( model_name='customfield', name='validation_maximum', - field=models.DecimalField(blank=True, decimal_places=2, max_digits=21, null=True), + field=models.DecimalField(blank=True, decimal_places=4, max_digits=16, null=True), ), migrations.AlterField( model_name='customfield', name='validation_minimum', - field=models.DecimalField(blank=True, decimal_places=2, max_digits=21, null=True), + field=models.DecimalField(blank=True, decimal_places=4, max_digits=16, null=True), ), ] diff --git a/netbox/extras/models/customfields.py b/netbox/extras/models/customfields.py index 78b30e9ab57..2e8728fce61 100644 --- a/netbox/extras/models/customfields.py +++ b/netbox/extras/models/customfields.py @@ -175,16 +175,16 @@ class CustomField(CloningMixin, ExportTemplatesMixin, ChangeLoggedModel): help_text=_('Fields with higher weights appear lower in a form.') ) validation_minimum = models.DecimalField( - max_digits=21, - decimal_places=2, + max_digits=16, + decimal_places=4, blank=True, null=True, verbose_name=_('minimum value'), help_text=_('Minimum allowed value (for numeric fields)') ) validation_maximum = models.DecimalField( - max_digits=21, - decimal_places=2, + max_digits=16, + decimal_places=4, blank=True, null=True, verbose_name=_('maximum value'), @@ -475,7 +475,7 @@ def to_form_field(self, set_initial=True, enforce_required=True, enforce_visibil field = forms.DecimalField( required=required, initial=initial, - max_digits=12, + max_digits=16, decimal_places=4, min_value=self.validation_minimum, max_value=self.validation_maximum From 017b17376178efb9fb81d03b27e19ae44505ef09 Mon Sep 17 00:00:00 2001 From: Jathn Date: Thu, 4 Sep 2025 14:10:36 +0300 Subject: [PATCH 3/5] Modify graphql to use FloatLookup instead of IntegerLookup --- netbox/extras/graphql/filters.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netbox/extras/graphql/filters.py b/netbox/extras/graphql/filters.py index 1712b705639..7c4766e63e0 100644 --- a/netbox/extras/graphql/filters.py +++ b/netbox/extras/graphql/filters.py @@ -17,7 +17,7 @@ ) from tenancy.graphql.filters import TenantFilter, TenantGroupFilter from netbox.graphql.enums import ColorEnum - from netbox.graphql.filter_lookups import IntegerLookup, JSONFilter, StringArrayLookup, TreeNodeFilter + from netbox.graphql.filter_lookups import FloatLookup, IntegerLookup, JSONFilter, StringArrayLookup, TreeNodeFilter from users.graphql.filters import GroupFilter, UserFilter from virtualization.graphql.filters import ClusterFilter, ClusterGroupFilter, ClusterTypeFilter from .enums import * @@ -143,10 +143,10 @@ class CustomFieldFilter(BaseObjectTypeFilterMixin, ChangeLogFilterMixin): weight: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) - validation_minimum: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( + validation_minimum: Annotated['FloatLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) - validation_maximum: Annotated['IntegerLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( + validation_maximum: Annotated['FloatLookup', strawberry.lazy('netbox.graphql.filter_lookups')] | None = ( strawberry_django.filter_field() ) validation_regex: FilterLookup[str] | None = strawberry_django.filter_field() From 3ea2939ebcf717a19ba99eb8ae9456cad6e4f50a Mon Sep 17 00:00:00 2001 From: Jathn Date: Thu, 4 Sep 2025 14:32:41 +0300 Subject: [PATCH 4/5] merged 4.4.0 release migrations --- .../extras/migrations/0133_merge_20250904_1132.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 netbox/extras/migrations/0133_merge_20250904_1132.py diff --git a/netbox/extras/migrations/0133_merge_20250904_1132.py b/netbox/extras/migrations/0133_merge_20250904_1132.py new file mode 100644 index 00000000000..acc1d8aa23f --- /dev/null +++ b/netbox/extras/migrations/0133_merge_20250904_1132.py @@ -0,0 +1,14 @@ +# Generated by Django 5.2.5 on 2025-09-04 11:32 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('extras', '0130_alter_customfield_validation_maximum_and_more'), + ('extras', '0132_configcontextprofile'), + ] + + operations = [ + ] From 28be6a726d738af0fbcba78baa58cfdce220f397 Mon Sep 17 00:00:00 2001 From: Jathn Date: Thu, 4 Sep 2025 16:01:49 +0300 Subject: [PATCH 5/5] Change duplicate entry 0130 from migration history and move new changes to 0133 --- ..._and_more.py => 0133_make_cf_minmax_decimal.py} | 4 +--- .../extras/migrations/0133_merge_20250904_1132.py | 14 -------------- 2 files changed, 1 insertion(+), 17 deletions(-) rename netbox/extras/migrations/{0130_alter_customfield_validation_maximum_and_more.py => 0133_make_cf_minmax_decimal.py} (85%) delete mode 100644 netbox/extras/migrations/0133_merge_20250904_1132.py diff --git a/netbox/extras/migrations/0130_alter_customfield_validation_maximum_and_more.py b/netbox/extras/migrations/0133_make_cf_minmax_decimal.py similarity index 85% rename from netbox/extras/migrations/0130_alter_customfield_validation_maximum_and_more.py rename to netbox/extras/migrations/0133_make_cf_minmax_decimal.py index 35f9a92a828..6ab7d25ea2a 100644 --- a/netbox/extras/migrations/0130_alter_customfield_validation_maximum_and_more.py +++ b/netbox/extras/migrations/0133_make_cf_minmax_decimal.py @@ -1,12 +1,10 @@ -# Generated by Django 5.2.4 on 2025-09-04 10:50 - from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ - ('extras', '0129_fix_script_paths'), + ('extras', '0132_configcontextprofile'), ] operations = [ diff --git a/netbox/extras/migrations/0133_merge_20250904_1132.py b/netbox/extras/migrations/0133_merge_20250904_1132.py deleted file mode 100644 index acc1d8aa23f..00000000000 --- a/netbox/extras/migrations/0133_merge_20250904_1132.py +++ /dev/null @@ -1,14 +0,0 @@ -# Generated by Django 5.2.5 on 2025-09-04 11:32 - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('extras', '0130_alter_customfield_validation_maximum_and_more'), - ('extras', '0132_configcontextprofile'), - ] - - operations = [ - ]