diff --git a/netbox/utilities/forms/fields.py b/netbox/utilities/forms/fields.py
index 71c14a6f0..661242c38 100644
--- a/netbox/utilities/forms/fields.py
+++ b/netbox/utilities/forms/fields.py
@@ -17,6 +17,7 @@ from django.urls import reverse
from utilities.choices import unpack_grouped_choices
from utilities.utils import content_type_identifier, content_type_name
from utilities.validators import EnhancedURLValidator
+from virtualization.choices import MemoryUnitChoices
from . import widgets
from .constants import *
from .utils import expand_alphanumeric_pattern, expand_ipaddress_pattern, parse_csv, validate_csv
@@ -41,6 +42,7 @@ __all__ = (
'JSONField',
'LaxURLField',
'MACAddressField',
+ 'MemoryField',
'SlugField',
'TagFilterField',
)
@@ -150,6 +152,40 @@ class MACAddressField(forms.Field):
return value
+class MemoryField(forms.MultiValueField):
+ widget = widgets.MemoryWidget
+ empty_values = ['', 'gb', 'mb', 'tb']
+
+ def __init__(self, **kwargs):
+ fields = (
+ forms.IntegerField(required=False),
+ forms.CharField(required=False),
+ )
+ super(MemoryField, self).__init__(
+ fields=fields, required=False,
+ require_all_fields=False, **kwargs
+ )
+
+ def compress(self, data):
+ if data:
+ value = data[0]
+ unit = data[1]
+
+ defs = {
+ 'gb': 1024**1,
+ 'tb': 1024**2,
+ }
+ if value:
+ if unit != MemoryUnitChoices.UNIT_MB:
+ return value * defs[unit]
+ else:
+ return value
+
+
+
+
+
+
#
# Content type fields
#
diff --git a/netbox/utilities/forms/widgets.py b/netbox/utilities/forms/widgets.py
index 6e227bb81..4625d7939 100644
--- a/netbox/utilities/forms/widgets.py
+++ b/netbox/utilities/forms/widgets.py
@@ -6,6 +6,7 @@ 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
__all__ = (
@@ -16,6 +17,7 @@ __all__ = (
'ColorSelect',
'DatePicker',
'DateTimePicker',
+ 'MemoryWidget',
'NumericArrayField',
'SelectSpeedWidget',
'SelectWithDisabled',
@@ -310,3 +312,21 @@ class TimePicker(forms.TextInput):
super().__init__(*args, **kwargs)
self.attrs['class'] = 'time-picker'
self.attrs['placeholder'] = 'hh:mm:ss'
+
+
+class MemoryWidget(forms.MultiWidget):
+ """
+ Memory Widget.
+ """
+ def __init__(self, attrs=None):
+ widget = (
+ forms.NumberInput(),
+ StaticSelect(choices=MemoryUnitChoices.choices)
+ )
+ super(MemoryWidget, self).__init__(widget, attrs)
+
+ def decompress(self, value):
+ if value:
+ return [value, '']
+ else:
+ return ['', '']
diff --git a/netbox/utilities/templates/form_helpers/render_field.html b/netbox/utilities/templates/form_helpers/render_field.html
index 9f3779bfe..f32bffedc 100644
--- a/netbox/utilities/templates/form_helpers/render_field.html
+++ b/netbox/utilities/templates/form_helpers/render_field.html
@@ -84,6 +84,25 @@
+{% elif field|widget_type == 'memorywidget'%}
+
+
+
+
+ {{ field }}
+
+ {% if bulk_nullable %}
+
+
+
+
+ {% endif %}
+
+
+
+
{% elif field|widget_type == 'selectmultiple' %}