diff --git a/netbox/utilities/forms/fields.py b/netbox/utilities/forms/fields.py index 607f351a2..0b15f4723 100644 --- a/netbox/utilities/forms/fields.py +++ b/netbox/utilities/forms/fields.py @@ -35,6 +35,7 @@ __all__ = ( 'CSVMultipleChoiceField', 'CSVMultipleContentTypeField', 'CSVTypedChoiceField', + 'DiskField', 'DynamicModelChoiceField', 'DynamicModelMultipleChoiceField', 'ExpandableIPAddressField', @@ -164,7 +165,7 @@ class MemoryField(forms.MultiValueField): fields = ( forms.IntegerField(required=False), forms.ChoiceField( - choices=MemoryUnitChoices.CHOICES, + choices=MemoryUnitChoices.MEMORY_CHOICES, required=False ), ) @@ -185,6 +186,38 @@ class MemoryField(forms.MultiValueField): raise forms.ValidationError("Please enter a memory value when unit is selected.") +class DiskField(forms.MultiValueField): + widget = widgets.DiskWidget + MULTIPLIERS = { + MemoryUnitChoices.UNIT_GB: 1024**0, + MemoryUnitChoices.UNIT_TB: 1024**1, + } + + def __init__(self, **kwargs): + fields = ( + forms.IntegerField(required=False), + forms.ChoiceField( + choices=MemoryUnitChoices.DISK_CHOICES, + required=False + ), + ) + super(DiskField, self).__init__( + fields=fields, required=False, + require_all_fields=False, **kwargs + ) + + @classmethod + def compress(cls, data): + if data: + size, unit = data + if size and not unit: + raise forms.ValidationError("Disk unit cannot be blank.") + elif size and unit: + return size * cls.MULTIPLIERS[unit] + elif not size and unit: + raise forms.ValidationError("Please enter a disk value when unit is selected.") + + # # Content type fields # diff --git a/netbox/utilities/forms/widgets.py b/netbox/utilities/forms/widgets.py index fca641751..62b7f6be3 100644 --- a/netbox/utilities/forms/widgets.py +++ b/netbox/utilities/forms/widgets.py @@ -6,8 +6,8 @@ from django.conf import settings from django.contrib.postgres.forms import SimpleArrayField from utilities.choices import ColorChoices -from virtualization.choices import MemoryUnitChoices from .utils import add_blank_choice, parse_numeric_range +from virtualization.choices import MemoryUnitChoices __all__ = ( 'APISelect', @@ -17,6 +17,7 @@ __all__ = ( 'ColorSelect', 'DatePicker', 'DateTimePicker', + 'DiskWidget', 'MemoryWidget', 'NumericArrayField', 'SelectSpeedWidget', @@ -321,7 +322,7 @@ class MemoryWidget(forms.MultiWidget): def __init__(self, attrs=None): widgets = ( forms.NumberInput(), - StaticSelect(choices=add_blank_choice(MemoryUnitChoices.CHOICES)) + StaticSelect(choices=add_blank_choice(MemoryUnitChoices.MEMORY_CHOICES)) ) super(MemoryWidget, self).__init__(widgets, attrs) @@ -330,3 +331,21 @@ class MemoryWidget(forms.MultiWidget): return [value, MemoryUnitChoices.UNIT_MB] else: return ['', ''] + + +class DiskWidget(forms.MultiWidget): + """ + Disk Widget. + """ + def __init__(self, attrs=None): + widgets = ( + forms.NumberInput(), + StaticSelect(choices=add_blank_choice(MemoryUnitChoices.DISK_CHOICES)) + ) + super(DiskWidget, self).__init__(widgets, attrs) + + def decompress(self, value): + if value: + return [value, MemoryUnitChoices.UNIT_GB] + else: + return ['', ''] diff --git a/netbox/utilities/templates/form_helpers/render_field.html b/netbox/utilities/templates/form_helpers/render_field.html index 64e5d6062..3f8b3734a 100644 --- a/netbox/utilities/templates/form_helpers/render_field.html +++ b/netbox/utilities/templates/form_helpers/render_field.html @@ -84,7 +84,7 @@ -{% elif field|widget_type == 'memorywidget'%} +{% elif field|widget_type == 'memorywidget' or field|widget_type == 'diskwidget' %}