Update forms for device & VM components
Some checks are pending
CI / build (20.x, 3.12) (push) Waiting to run
CI / build (20.x, 3.13) (push) Waiting to run

This commit is contained in:
Jeremy Stretch
2025-10-21 16:59:53 -04:00
parent cd485a5c91
commit 4dda968687
8 changed files with 44 additions and 35 deletions

View File

@@ -13,7 +13,7 @@ from netbox.choices import *
from netbox.forms import ( from netbox.forms import (
NestedGroupModelBulkEditForm, NetBoxModelBulkEditForm, OrganizationalModelBulkEditForm, PrimaryModelBulkEditForm, NestedGroupModelBulkEditForm, NetBoxModelBulkEditForm, OrganizationalModelBulkEditForm, PrimaryModelBulkEditForm,
) )
from netbox.forms.mixins import ChangelogMessageMixin from netbox.forms.mixins import ChangelogMessageMixin, OwnerMixin
from tenancy.models import Tenant from tenancy.models import Tenant
from users.models import User from users.models import User
from utilities.forms import BulkEditForm, add_blank_choice, form_from_model from utilities.forms import BulkEditForm, add_blank_choice, form_from_model
@@ -1246,7 +1246,7 @@ class InventoryItemTemplateBulkEditForm(ComponentTemplateBulkEditForm):
# Device components # Device components
# #
class ComponentBulkEditForm(NetBoxModelBulkEditForm): class ComponentBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
device = forms.ModelChoiceField( device = forms.ModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),

View File

@@ -12,7 +12,7 @@ from extras.models import ConfigTemplate
from ipam.models import VRF, IPAddress from ipam.models import VRF, IPAddress
from netbox.choices import * from netbox.choices import *
from netbox.forms import ( from netbox.forms import (
NestedGroupModelBulkImportForm, NetBoxModelImportForm, OrganizationalModelBulkImportForm, NestedGroupModelBulkImportForm, NetBoxModelImportForm, OrganizationalModelBulkImportForm, OwnerCSVMixin,
PrimaryModelBulkImportForm, PrimaryModelBulkImportForm,
) )
from tenancy.models import Tenant from tenancy.models import Tenant
@@ -779,7 +779,7 @@ class ModuleImportForm(ModuleCommonForm, PrimaryModelBulkImportForm):
# Device components # Device components
# #
class ConsolePortImportForm(NetBoxModelImportForm): class ConsolePortImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -802,10 +802,10 @@ class ConsolePortImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = ConsolePort model = ConsolePort
fields = ('device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags') fields = ('device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'owner', 'tags')
class ConsoleServerPortImportForm(NetBoxModelImportForm): class ConsoleServerPortImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -828,10 +828,10 @@ class ConsoleServerPortImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = ConsoleServerPort model = ConsoleServerPort
fields = ('device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags') fields = ('device', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'owner', 'tags')
class PowerPortImportForm(NetBoxModelImportForm): class PowerPortImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -847,11 +847,12 @@ class PowerPortImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = PowerPort model = PowerPort
fields = ( fields = (
'device', 'name', 'label', 'type', 'mark_connected', 'maximum_draw', 'allocated_draw', 'description', 'tags' 'device', 'name', 'label', 'type', 'mark_connected', 'maximum_draw', 'allocated_draw', 'description',
'owner', 'tags',
) )
class PowerOutletImportForm(NetBoxModelImportForm): class PowerOutletImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -881,7 +882,7 @@ class PowerOutletImportForm(NetBoxModelImportForm):
model = PowerOutlet model = PowerOutlet
fields = ( fields = (
'device', 'name', 'label', 'type', 'color', 'mark_connected', 'power_port', 'feed_leg', 'description', 'device', 'name', 'label', 'type', 'color', 'mark_connected', 'power_port', 'feed_leg', 'description',
'tags', 'owner', 'tags',
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@@ -907,7 +908,7 @@ class PowerOutletImportForm(NetBoxModelImportForm):
self.fields['power_port'].queryset = PowerPort.objects.none() self.fields['power_port'].queryset = PowerPort.objects.none()
class InterfaceImportForm(NetBoxModelImportForm): class InterfaceImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -990,7 +991,7 @@ class InterfaceImportForm(NetBoxModelImportForm):
fields = ( fields = (
'device', 'name', 'label', 'parent', 'bridge', 'lag', 'type', 'speed', 'duplex', 'enabled', 'device', 'name', 'label', 'parent', 'bridge', 'lag', 'type', 'speed', 'duplex', 'enabled',
'mark_connected', 'wwn', 'vdcs', 'mtu', 'mgmt_only', 'description', 'poe_mode', 'poe_type', 'mode', 'mark_connected', 'wwn', 'vdcs', 'mtu', 'mgmt_only', 'description', 'poe_mode', 'poe_type', 'mode',
'vrf', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'tags' 'vrf', 'rf_role', 'rf_channel', 'rf_channel_frequency', 'rf_channel_width', 'tx_power', 'owner', 'tags'
) )
def __init__(self, data=None, *args, **kwargs): def __init__(self, data=None, *args, **kwargs):
@@ -1025,7 +1026,7 @@ class InterfaceImportForm(NetBoxModelImportForm):
return self.cleaned_data['vdcs'] return self.cleaned_data['vdcs']
class FrontPortImportForm(NetBoxModelImportForm): class FrontPortImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -1047,7 +1048,7 @@ class FrontPortImportForm(NetBoxModelImportForm):
model = FrontPort model = FrontPort
fields = ( fields = (
'device', 'name', 'label', 'type', 'color', 'mark_connected', 'rear_port', 'rear_port_position', 'device', 'name', 'label', 'type', 'color', 'mark_connected', 'rear_port', 'rear_port_position',
'description', 'tags' 'description', 'owner', 'tags'
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
@@ -1073,7 +1074,7 @@ class FrontPortImportForm(NetBoxModelImportForm):
self.fields['rear_port'].queryset = RearPort.objects.none() self.fields['rear_port'].queryset = RearPort.objects.none()
class RearPortImportForm(NetBoxModelImportForm): class RearPortImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -1087,10 +1088,12 @@ class RearPortImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = RearPort model = RearPort
fields = ('device', 'name', 'label', 'type', 'color', 'mark_connected', 'positions', 'description', 'tags') fields = (
'device', 'name', 'label', 'type', 'color', 'mark_connected', 'positions', 'description', 'owner', 'tags',
)
class ModuleBayImportForm(NetBoxModelImportForm): class ModuleBayImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -1099,10 +1102,10 @@ class ModuleBayImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = ModuleBay model = ModuleBay
fields = ('device', 'name', 'label', 'position', 'description', 'tags') fields = ('device', 'name', 'label', 'position', 'description', 'owner', 'tags')
class DeviceBayImportForm(NetBoxModelImportForm): class DeviceBayImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),
@@ -1121,7 +1124,7 @@ class DeviceBayImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = DeviceBay model = DeviceBay
fields = ('device', 'name', 'label', 'installed_device', 'description', 'tags') fields = ('device', 'name', 'label', 'installed_device', 'description', 'owner', 'tags')
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@@ -1150,7 +1153,7 @@ class DeviceBayImportForm(NetBoxModelImportForm):
self.fields['installed_device'].queryset = Device.objects.none() self.fields['installed_device'].queryset = Device.objects.none()
class InventoryItemImportForm(OrganizationalModelBulkImportForm): class InventoryItemImportForm(OwnerCSVMixin, NetBoxModelImportForm):
device = CSVModelChoiceField( device = CSVModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),

View File

@@ -12,6 +12,7 @@ from netbox.forms import (
NestedGroupModelFilterSetForm, NetBoxModelFilterSetForm, OrganizationalModelFilterSetForm, NestedGroupModelFilterSetForm, NetBoxModelFilterSetForm, OrganizationalModelFilterSetForm,
PrimaryModelFilterSetForm, PrimaryModelFilterSetForm,
) )
from netbox.forms.mixins import OwnerMixin
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from users.models import User from users.models import User
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm, add_blank_choice from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, FilterForm, add_blank_choice
@@ -63,7 +64,7 @@ __all__ = (
) )
class DeviceComponentFilterForm(NetBoxModelFilterSetForm): class DeviceComponentFilterForm(OwnerMixin, NetBoxModelFilterSetForm):
name = forms.CharField( name = forms.CharField(
label=_('Name'), label=_('Name'),
required=False required=False

View File

@@ -11,7 +11,7 @@ from extras.models import ConfigTemplate
from ipam.choices import VLANQinQRoleChoices from ipam.choices import VLANQinQRoleChoices
from ipam.models import ASN, IPAddress, VLAN, VLANGroup, VLANTranslationPolicy, VRF from ipam.models import ASN, IPAddress, VLAN, VLANGroup, VLANTranslationPolicy, VRF
from netbox.forms import NestedGroupModelForm, NetBoxModelForm, OrganizationalModelForm, PrimaryModelForm from netbox.forms import NestedGroupModelForm, NetBoxModelForm, OrganizationalModelForm, PrimaryModelForm
from netbox.forms.mixins import ChangelogMessageMixin from netbox.forms.mixins import ChangelogMessageMixin, OwnerMixin
from tenancy.forms import TenancyForm from tenancy.forms import TenancyForm
from users.models import User from users.models import User
from utilities.forms import add_blank_choice, get_field_value from utilities.forms import add_blank_choice, get_field_value
@@ -1334,7 +1334,7 @@ class InventoryItemTemplateForm(ComponentTemplateForm):
# Device components # Device components
# #
class DeviceComponentForm(NetBoxModelForm): class DeviceComponentForm(OwnerMixin, NetBoxModelForm):
device = DynamicModelChoiceField( device = DynamicModelChoiceField(
label=_('Device'), label=_('Device'),
queryset=Device.objects.all(), queryset=Device.objects.all(),

View File

@@ -8,6 +8,7 @@ from dcim.models import Device, DeviceRole, Platform, Site
from extras.models import ConfigTemplate from extras.models import ConfigTemplate
from ipam.models import VLAN, VLANGroup, VLANTranslationPolicy, VRF from ipam.models import VLAN, VLANGroup, VLANTranslationPolicy, VRF
from netbox.forms import NetBoxModelBulkEditForm, OrganizationalModelBulkEditForm, PrimaryModelBulkEditForm from netbox.forms import NetBoxModelBulkEditForm, OrganizationalModelBulkEditForm, PrimaryModelBulkEditForm
from netbox.forms.mixins import OwnerMixin
from tenancy.models import Tenant from tenancy.models import Tenant
from utilities.forms import BulkRenameForm, add_blank_choice from utilities.forms import BulkRenameForm, add_blank_choice
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField
@@ -153,7 +154,7 @@ class VirtualMachineBulkEditForm(PrimaryModelBulkEditForm):
) )
class VMInterfaceBulkEditForm(NetBoxModelBulkEditForm): class VMInterfaceBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
virtual_machine = forms.ModelChoiceField( virtual_machine = forms.ModelChoiceField(
label=_('Virtual machine'), label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
@@ -287,7 +288,7 @@ class VMInterfaceBulkRenameForm(BulkRenameForm):
) )
class VirtualDiskBulkEditForm(NetBoxModelBulkEditForm): class VirtualDiskBulkEditForm(OwnerMixin, NetBoxModelBulkEditForm):
virtual_machine = forms.ModelChoiceField( virtual_machine = forms.ModelChoiceField(
label=_('Virtual machine'), label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),

View File

@@ -5,7 +5,9 @@ from dcim.forms.mixins import ScopedImportForm
from dcim.models import Device, DeviceRole, Platform, Site from dcim.models import Device, DeviceRole, Platform, Site
from extras.models import ConfigTemplate from extras.models import ConfigTemplate
from ipam.models import VRF from ipam.models import VRF
from netbox.forms import NetBoxModelImportForm, OrganizationalModelBulkImportForm, PrimaryModelBulkImportForm from netbox.forms import (
NetBoxModelImportForm, OrganizationalModelBulkImportForm, OwnerCSVMixin, PrimaryModelBulkImportForm,
)
from tenancy.models import Tenant from tenancy.models import Tenant
from utilities.forms.fields import CSVChoiceField, CSVModelChoiceField from utilities.forms.fields import CSVChoiceField, CSVModelChoiceField
from virtualization.choices import * from virtualization.choices import *
@@ -146,7 +148,7 @@ class VirtualMachineImportForm(PrimaryModelBulkImportForm):
) )
class VMInterfaceImportForm(NetBoxModelImportForm): class VMInterfaceImportForm(OwnerCSVMixin, NetBoxModelImportForm):
virtual_machine = CSVModelChoiceField( virtual_machine = CSVModelChoiceField(
label=_('Virtual machine'), label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
@@ -184,7 +186,7 @@ class VMInterfaceImportForm(NetBoxModelImportForm):
model = VMInterface model = VMInterface
fields = ( fields = (
'virtual_machine', 'name', 'parent', 'bridge', 'enabled', 'mtu', 'description', 'mode', 'virtual_machine', 'name', 'parent', 'bridge', 'enabled', 'mtu', 'description', 'mode',
'vrf', 'tags' 'vrf', 'owner', 'tags'
) )
def __init__(self, data=None, *args, **kwargs): def __init__(self, data=None, *args, **kwargs):
@@ -207,7 +209,7 @@ class VMInterfaceImportForm(NetBoxModelImportForm):
return self.cleaned_data['enabled'] return self.cleaned_data['enabled']
class VirtualDiskImportForm(NetBoxModelImportForm): class VirtualDiskImportForm(OwnerCSVMixin, NetBoxModelImportForm):
virtual_machine = CSVModelChoiceField( virtual_machine = CSVModelChoiceField(
label=_('Virtual machine'), label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),
@@ -217,5 +219,5 @@ class VirtualDiskImportForm(NetBoxModelImportForm):
class Meta: class Meta:
model = VirtualDisk model = VirtualDisk
fields = ( fields = (
'virtual_machine', 'name', 'size', 'description', 'tags' 'virtual_machine', 'name', 'size', 'description', 'owner', 'tags'
) )

View File

@@ -7,6 +7,7 @@ from extras.forms import LocalConfigContextFilterForm
from extras.models import ConfigTemplate from extras.models import ConfigTemplate
from ipam.models import VRF, VLANTranslationPolicy from ipam.models import VRF, VLANTranslationPolicy
from netbox.forms import NetBoxModelFilterSetForm, OrganizationalModelFilterSetForm, PrimaryModelFilterSetForm from netbox.forms import NetBoxModelFilterSetForm, OrganizationalModelFilterSetForm, PrimaryModelFilterSetForm
from netbox.forms.mixins import OwnerMixin
from tenancy.forms import ContactModelFilterForm, TenancyFilterForm from tenancy.forms import ContactModelFilterForm, TenancyFilterForm
from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES
from utilities.forms.fields import DynamicModelMultipleChoiceField, TagFilterField from utilities.forms.fields import DynamicModelMultipleChoiceField, TagFilterField
@@ -199,7 +200,7 @@ class VirtualMachineFilterForm(
tag = TagFilterField(model) tag = TagFilterField(model)
class VMInterfaceFilterForm(NetBoxModelFilterSetForm): class VMInterfaceFilterForm(OwnerMixin, NetBoxModelFilterSetForm):
model = VMInterface model = VMInterface
fieldsets = ( fieldsets = (
FieldSet('q', 'filter_id', 'tag', 'owner_id'), FieldSet('q', 'filter_id', 'tag', 'owner_id'),
@@ -256,7 +257,7 @@ class VMInterfaceFilterForm(NetBoxModelFilterSetForm):
tag = TagFilterField(model) tag = TagFilterField(model)
class VirtualDiskFilterForm(NetBoxModelFilterSetForm): class VirtualDiskFilterForm(OwnerMixin, NetBoxModelFilterSetForm):
model = VirtualDisk model = VirtualDisk
fieldsets = ( fieldsets = (
FieldSet('q', 'filter_id', 'tag', 'owner_id'), FieldSet('q', 'filter_id', 'tag', 'owner_id'),

View File

@@ -11,6 +11,7 @@ from extras.models import ConfigTemplate
from ipam.choices import VLANQinQRoleChoices from ipam.choices import VLANQinQRoleChoices
from ipam.models import IPAddress, VLAN, VLANGroup, VLANTranslationPolicy, VRF from ipam.models import IPAddress, VLAN, VLANGroup, VLANTranslationPolicy, VRF
from netbox.forms import NetBoxModelForm, OrganizationalModelForm, PrimaryModelForm from netbox.forms import NetBoxModelForm, OrganizationalModelForm, PrimaryModelForm
from netbox.forms.mixins import OwnerMixin
from tenancy.forms import TenancyForm from tenancy.forms import TenancyForm
from utilities.forms import ConfirmationForm from utilities.forms import ConfirmationForm
from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, JSONField
@@ -280,7 +281,7 @@ class VirtualMachineForm(TenancyForm, PrimaryModelForm):
# Virtual machine components # Virtual machine components
# #
class VMComponentForm(NetBoxModelForm): class VMComponentForm(OwnerMixin, NetBoxModelForm):
virtual_machine = DynamicModelChoiceField( virtual_machine = DynamicModelChoiceField(
label=_('Virtual machine'), label=_('Virtual machine'),
queryset=VirtualMachine.objects.all(), queryset=VirtualMachine.objects.all(),