Fixes #21095: Add IEC unit labels support and rename humanize helpers to be unit-agnostic (#21789)

This commit is contained in:
Jonathan Senecal
2026-04-02 17:30:49 -04:00
committed by GitHub
parent 40eec679d9
commit a19daa5466
12 changed files with 153 additions and 36 deletions

View File

@@ -1,4 +1,5 @@
from django import forms
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from dcim.choices import InterfaceModeChoices
@@ -13,6 +14,7 @@ from tenancy.models import Tenant
from utilities.forms import BulkRenameForm, add_blank_choice
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
from utilities.forms.rendering import FieldSet
from utilities.forms.utils import get_capacity_unit_label
from utilities.forms.widgets import BulkEditNullBooleanSelect
from virtualization.choices import *
from virtualization.models import *
@@ -138,11 +140,11 @@ class VirtualMachineBulkEditForm(PrimaryModelBulkEditForm):
)
memory = forms.IntegerField(
required=False,
label=_('Memory (MB)')
label=_('Memory')
)
disk = forms.IntegerField(
required=False,
label=_('Disk (MB)')
label=_('Disk')
)
config_template = DynamicModelChoiceField(
queryset=ConfigTemplate.objects.all(),
@@ -159,6 +161,13 @@ class VirtualMachineBulkEditForm(PrimaryModelBulkEditForm):
'site', 'cluster', 'device', 'role', 'tenant', 'platform', 'vcpus', 'memory', 'disk', 'description', 'comments',
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set unit labels based on configured RAM_BASE_UNIT / DISK_BASE_UNIT (MB vs MiB)
self.fields['memory'].label = _('Memory ({unit})').format(unit=get_capacity_unit_label(settings.RAM_BASE_UNIT))
self.fields['disk'].label = _('Disk ({unit})').format(unit=get_capacity_unit_label(settings.DISK_BASE_UNIT))
class VMInterfaceBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
virtual_machine = forms.ModelChoiceField(
@@ -304,7 +313,7 @@ class VirtualDiskBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
)
size = forms.IntegerField(
required=False,
label=_('Size (MB)')
label=_('Size')
)
description = forms.CharField(
label=_('Description'),
@@ -318,6 +327,12 @@ class VirtualDiskBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
)
nullable_fields = ('description',)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set unit label based on configured DISK_BASE_UNIT (MB vs MiB)
self.fields['size'].label = _('Size ({unit})').format(unit=get_capacity_unit_label(settings.DISK_BASE_UNIT))
class VirtualDiskBulkRenameForm(BulkRenameForm):
pk = forms.ModelMultipleChoiceField(

View File

@@ -1,4 +1,5 @@
from django import forms
from django.conf import settings
from django.utils.translation import gettext_lazy as _
from dcim.choices import *
@@ -12,6 +13,7 @@ from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
from utilities.forms.fields import DynamicModelMultipleChoiceField, TagFilterField
from utilities.forms.rendering import FieldSet
from utilities.forms.utils import get_capacity_unit_label
from virtualization.choices import *
from virtualization.models import *
from vpn.models import L2VPN
@@ -281,8 +283,14 @@ class VirtualDiskFilterForm(OwnerFilterMixin, NetBoxModelFilterSetForm):
label=_('Virtual machine')
)
size = forms.IntegerField(
label=_('Size (MB)'),
label=_('Size'),
required=False,
min_value=1
)
tag = TagFilterField(model)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set unit label based on configured DISK_BASE_UNIT (MB vs MiB)
self.fields['size'].label = _('Size ({unit})').format(unit=get_capacity_unit_label(settings.DISK_BASE_UNIT))

View File

@@ -1,5 +1,6 @@
from django import forms
from django.apps import apps
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
@@ -16,6 +17,7 @@ from tenancy.forms import TenancyForm
from utilities.forms import ConfirmationForm
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField
from utilities.forms.rendering import FieldSet
from utilities.forms.utils import get_capacity_unit_label
from utilities.forms.widgets import HTMXSelect
from virtualization.models import *
@@ -236,6 +238,10 @@ class VirtualMachineForm(TenancyForm, PrimaryModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set unit labels based on configured RAM_BASE_UNIT / DISK_BASE_UNIT (MB vs MiB)
self.fields['memory'].label = _('Memory ({unit})').format(unit=get_capacity_unit_label(settings.RAM_BASE_UNIT))
self.fields['disk'].label = _('Disk ({unit})').format(unit=get_capacity_unit_label(settings.DISK_BASE_UNIT))
if self.instance.pk:
# Disable the disk field if one or more VirtualDisks have been created
@@ -401,3 +407,9 @@ class VirtualDiskForm(VMComponentForm):
fields = [
'virtual_machine', 'name', 'size', 'description', 'owner', 'tags',
]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Set unit label based on configured DISK_BASE_UNIT (MB vs MiB)
self.fields['size'].label = _('Size ({unit})').format(unit=get_capacity_unit_label(settings.DISK_BASE_UNIT))

View File

@@ -121,12 +121,12 @@ class VirtualMachine(ContactsMixin, ImageAttachmentsMixin, RenderConfigMixin, Co
memory = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name=_('memory (MB)')
verbose_name=_('memory')
)
disk = models.PositiveIntegerField(
blank=True,
null=True,
verbose_name=_('disk (MB)')
verbose_name=_('disk')
)
serial = models.CharField(
verbose_name=_('serial number'),
@@ -425,7 +425,7 @@ class VMInterface(ComponentModel, BaseInterface, TrackingModelMixin):
class VirtualDisk(ComponentModel, TrackingModelMixin):
size = models.PositiveIntegerField(
verbose_name=_('size (MB)'),
verbose_name=_('size'),
)
class Meta(ComponentModel.Meta):

View File

@@ -4,7 +4,7 @@ from django.utils.translation import gettext_lazy as _
from dcim.tables.devices import BaseInterfaceTable
from netbox.tables import NetBoxTable, PrimaryModelTable, columns
from tenancy.tables import ContactsColumnMixin, TenancyColumnsMixin
from utilities.templatetags.helpers import humanize_disk_megabytes
from utilities.templatetags.helpers import humanize_disk_capacity, humanize_ram_capacity
from virtualization.models import VirtualDisk, VirtualMachine, VMInterface
from .template_code import *
@@ -93,8 +93,11 @@ class VirtualMachineTable(TenancyColumnsMixin, ContactsColumnMixin, PrimaryModel
'pk', 'name', 'status', 'site', 'cluster', 'role', 'tenant', 'vcpus', 'memory', 'disk', 'primary_ip',
)
def render_memory(self, value):
return humanize_ram_capacity(value)
def render_disk(self, value):
return humanize_disk_megabytes(value)
return humanize_disk_capacity(value)
#
@@ -184,7 +187,7 @@ class VirtualDiskTable(NetBoxTable):
}
def render_size(self, value):
return humanize_disk_megabytes(value)
return humanize_disk_capacity(value)
class VirtualMachineVirtualDiskTable(VirtualDiskTable):