diff --git a/netbox/dcim/forms/models.py b/netbox/dcim/forms/models.py
index d1d5b1683..d2d6af4aa 100644
--- a/netbox/dcim/forms/models.py
+++ b/netbox/dcim/forms/models.py
@@ -986,47 +986,57 @@ class VCMemberSelectForm(BootstrapMixin, forms.Form):
# Device component templates
#
+class ComponentTemplateForm(BootstrapMixin, forms.ModelForm):
+ device_type = DynamicModelChoiceField(
+ queryset=DeviceType.objects.all()
+ )
-class ConsolePortTemplateForm(BootstrapMixin, forms.ModelForm):
+
+class ModularComponentTemplateForm(BootstrapMixin, forms.ModelForm):
+ device_type = DynamicModelChoiceField(
+ queryset=DeviceType.objects.all(),
+ required=False
+ )
+ module_type = DynamicModelChoiceField(
+ queryset=ModuleType.objects.all(),
+ required=False
+ )
+
+
+class ConsolePortTemplateForm(ModularComponentTemplateForm):
class Meta:
model = ConsolePortTemplate
fields = [
'device_type', 'module_type', 'name', 'label', 'type', 'description',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect,
}
-class ConsoleServerPortTemplateForm(BootstrapMixin, forms.ModelForm):
+class ConsoleServerPortTemplateForm(ModularComponentTemplateForm):
class Meta:
model = ConsoleServerPortTemplate
fields = [
'device_type', 'module_type', 'name', 'label', 'type', 'description',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect,
}
-class PowerPortTemplateForm(BootstrapMixin, forms.ModelForm):
+class PowerPortTemplateForm(ModularComponentTemplateForm):
class Meta:
model = PowerPortTemplate
fields = [
'device_type', 'module_type', 'name', 'label', 'type', 'maximum_draw', 'allocated_draw', 'description',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect(),
}
-class PowerOutletTemplateForm(BootstrapMixin, forms.ModelForm):
+class PowerOutletTemplateForm(ModularComponentTemplateForm):
power_port = DynamicModelChoiceField(
queryset=PowerPortTemplate.objects.all(),
required=False,
@@ -1041,29 +1051,25 @@ class PowerOutletTemplateForm(BootstrapMixin, forms.ModelForm):
'device_type', 'module_type', 'name', 'label', 'type', 'power_port', 'feed_leg', 'description',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect(),
'feed_leg': StaticSelect(),
}
-class InterfaceTemplateForm(BootstrapMixin, forms.ModelForm):
+class InterfaceTemplateForm(ModularComponentTemplateForm):
class Meta:
model = InterfaceTemplate
fields = [
'device_type', 'module_type', 'name', 'label', 'type', 'mgmt_only', 'description', 'poe_mode', 'poe_type',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect(),
'poe_mode': StaticSelect(),
'poe_type': StaticSelect(),
}
-class FrontPortTemplateForm(BootstrapMixin, forms.ModelForm):
+class FrontPortTemplateForm(ModularComponentTemplateForm):
rear_port = DynamicModelChoiceField(
queryset=RearPortTemplate.objects.all(),
required=False,
@@ -1080,48 +1086,38 @@ class FrontPortTemplateForm(BootstrapMixin, forms.ModelForm):
'description',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect(),
}
-class RearPortTemplateForm(BootstrapMixin, forms.ModelForm):
+class RearPortTemplateForm(ModularComponentTemplateForm):
class Meta:
model = RearPortTemplate
fields = [
'device_type', 'module_type', 'name', 'label', 'type', 'color', 'positions', 'description',
]
widgets = {
- 'device_type': forms.HiddenInput(),
- 'module_type': forms.HiddenInput(),
'type': StaticSelect(),
}
-class ModuleBayTemplateForm(BootstrapMixin, forms.ModelForm):
+class ModuleBayTemplateForm(ComponentTemplateForm):
class Meta:
model = ModuleBayTemplate
fields = [
'device_type', 'name', 'label', 'position', 'description',
]
- widgets = {
- 'device_type': forms.HiddenInput(),
- }
-class DeviceBayTemplateForm(BootstrapMixin, forms.ModelForm):
+class DeviceBayTemplateForm(ComponentTemplateForm):
class Meta:
model = DeviceBayTemplate
fields = [
'device_type', 'name', 'label', 'description',
]
- widgets = {
- 'device_type': forms.HiddenInput(),
- }
-class InventoryItemTemplateForm(BootstrapMixin, forms.ModelForm):
+class InventoryItemTemplateForm(ComponentTemplateForm):
parent = DynamicModelChoiceField(
queryset=InventoryItemTemplate.objects.all(),
required=False,
@@ -1154,9 +1150,6 @@ class InventoryItemTemplateForm(BootstrapMixin, forms.ModelForm):
'device_type', 'parent', 'name', 'label', 'role', 'manufacturer', 'part_id', 'description',
'component_type', 'component_id',
]
- widgets = {
- 'device_type': forms.HiddenInput(),
- }
#
@@ -1164,6 +1157,9 @@ class InventoryItemTemplateForm(BootstrapMixin, forms.ModelForm):
#
class ConsolePortForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1178,13 +1174,15 @@ class ConsolePortForm(NetBoxModelForm):
'device', 'module', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
'speed': StaticSelect(),
}
class ConsoleServerPortForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1199,13 +1197,15 @@ class ConsoleServerPortForm(NetBoxModelForm):
'device', 'module', 'name', 'label', 'type', 'speed', 'mark_connected', 'description', 'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
'speed': StaticSelect(),
}
class PowerPortForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1222,12 +1222,14 @@ class PowerPortForm(NetBoxModelForm):
'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
}
class PowerOutletForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1250,13 +1252,15 @@ class PowerOutletForm(NetBoxModelForm):
'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
'feed_leg': StaticSelect(),
}
class InterfaceForm(InterfaceCommonForm, NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1352,7 +1356,6 @@ class InterfaceForm(InterfaceCommonForm, NetBoxModelForm):
'untagged_vlan', 'tagged_vlans', 'vrf', 'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
'speed': SelectSpeedWidget(),
'poe_mode': StaticSelect(),
@@ -1383,6 +1386,9 @@ class InterfaceForm(InterfaceCommonForm, NetBoxModelForm):
class FrontPortForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1404,12 +1410,14 @@ class FrontPortForm(NetBoxModelForm):
'description', 'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
}
class RearPortForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
module = DynamicModelChoiceField(
queryset=Module.objects.all(),
required=False,
@@ -1424,33 +1432,32 @@ class RearPortForm(NetBoxModelForm):
'device', 'module', 'name', 'label', 'type', 'color', 'positions', 'mark_connected', 'description', 'tags',
]
widgets = {
- 'device': forms.HiddenInput(),
'type': StaticSelect(),
}
class ModuleBayForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
class Meta:
model = ModuleBay
fields = [
'device', 'name', 'label', 'position', 'description', 'tags',
]
- widgets = {
- 'device': forms.HiddenInput(),
- }
class DeviceBayForm(NetBoxModelForm):
+ device = DynamicModelChoiceField(
+ queryset=Device.objects.all()
+ )
class Meta:
model = DeviceBay
fields = [
'device', 'name', 'label', 'description', 'tags',
]
- widgets = {
- 'device': forms.HiddenInput(),
- }
class PopulateDeviceBayForm(BootstrapMixin, forms.Form):
diff --git a/netbox/dcim/forms/object_create.py b/netbox/dcim/forms/object_create.py
index d2c941b34..75283509a 100644
--- a/netbox/dcim/forms/object_create.py
+++ b/netbox/dcim/forms/object_create.py
@@ -2,103 +2,108 @@ from django import forms
from dcim.models import *
from netbox.forms import NetBoxModelForm
-from utilities.forms import (
- BootstrapMixin, DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField,
-)
+from utilities.forms import DynamicModelChoiceField, DynamicModelMultipleChoiceField, ExpandableNameField
+from . import models as model_forms
__all__ = (
- 'ComponentTemplateCreateForm',
- 'DeviceComponentCreateForm',
+ 'ComponentCreateForm',
+ 'ConsolePortCreateForm',
+ 'ConsolePortTemplateCreateForm',
+ 'ConsoleServerPortCreateForm',
+ 'ConsoleServerPortTemplateCreateForm',
+ 'DeviceBayCreateForm',
+ 'DeviceBayTemplateCreateForm',
'FrontPortCreateForm',
'FrontPortTemplateCreateForm',
+ 'InterfaceCreateForm',
+ 'InterfaceTemplateCreateForm',
'InventoryItemCreateForm',
- 'ModularComponentTemplateCreateForm',
+ 'InventoryItemTemplateCreateForm',
'ModuleBayCreateForm',
'ModuleBayTemplateCreateForm',
+ 'PowerOutletCreateForm',
+ 'PowerOutletTemplateCreateForm',
+ 'PowerPortCreateForm',
+ 'PowerPortTemplateCreateForm',
+ 'RearPortCreateForm',
+ 'RearPortTemplateCreateForm',
'VirtualChassisCreateForm',
)
-class ComponentCreateForm(BootstrapMixin, forms.Form):
+class ComponentCreateForm(forms.Form):
"""
Subclass this form when facilitating the creation of one or more device component or component templates based on
a name pattern.
"""
- name_pattern = ExpandableNameField(
- label='Name'
- )
- label_pattern = ExpandableNameField(
- label='Label',
+ name = ExpandableNameField()
+ label = ExpandableNameField(
required=False,
help_text='Alphanumeric ranges are supported. (Must match the number of names being created.)'
)
- def clean(self):
- super().clean()
-
- # Validate that all patterned fields generate an equal number of values
- patterned_fields = [
- field_name for field_name in self.fields if field_name.endswith('_pattern')
- ]
- pattern_count = len(self.cleaned_data['name_pattern'])
- for field_name in patterned_fields:
- value_count = len(self.cleaned_data[field_name])
- if self.cleaned_data[field_name] and value_count != pattern_count:
- raise forms.ValidationError({
- field_name: f'The provided pattern specifies {value_count} values, but {pattern_count} are '
- f'expected.'
- }, code='label_pattern_mismatch')
+ # TODO: Incorporate this validation
+ # def clean(self):
+ # super().clean()
+ #
+ # # Validate that all patterned fields generate an equal number of values
+ # patterned_fields = [
+ # field_name for field_name in self.fields if field_name.endswith('_pattern')
+ # ]
+ # pattern_count = len(self.cleaned_data['name_pattern'])
+ # for field_name in patterned_fields:
+ # value_count = len(self.cleaned_data[field_name])
+ # if self.cleaned_data[field_name] and value_count != pattern_count:
+ # raise forms.ValidationError({
+ # field_name: f'The provided pattern specifies {value_count} values, but {pattern_count} are '
+ # f'expected.'
+ # }, code='label_pattern_mismatch')
-class ComponentTemplateCreateForm(ComponentCreateForm):
- """
- Creation form for component templates that can be assigned only to a DeviceType.
- """
- device_type = DynamicModelChoiceField(
- queryset=DeviceType.objects.all(),
- )
- field_order = ('device_type', 'name_pattern', 'label_pattern')
+# class ModularComponentTemplateCreateForm(ComponentCreateForm):
+# """
+# Creation form for component templates that can be assigned to either a DeviceType *or* a ModuleType.
+# """
+# name = ExpandableNameField(
+# label='Name',
+# help_text="""
+# Alphanumeric ranges are supported for bulk creation. Mixed cases and types within a single range
+# are not supported. Example: [ge,xe]-0/0/[0-9]
. {module} is accepted as a substitution for
+# the module bay position.
+# """
+# )
-class ModularComponentTemplateCreateForm(ComponentCreateForm):
- """
- Creation form for component templates that can be assigned to either a DeviceType *or* a ModuleType.
- """
- name_pattern = ExpandableNameField(
- label='Name',
- help_text="""
- Alphanumeric ranges are supported for bulk creation. Mixed cases and types within a single range
- are not supported. Example: [ge,xe]-0/0/[0-9]
. {module} is accepted as a substitution for
- the module bay position.
- """
- )
- device_type = DynamicModelChoiceField(
- queryset=DeviceType.objects.all(),
- required=False
- )
- module_type = DynamicModelChoiceField(
- queryset=ModuleType.objects.all(),
- required=False
- )
- field_order = ('device_type', 'module_type', 'name_pattern', 'label_pattern')
+#
+# Device component templates
+#
+
+class ConsolePortTemplateCreateForm(ComponentCreateForm, model_forms.ConsolePortTemplateForm):
+ pass
-class DeviceComponentCreateForm(ComponentCreateForm):
- device = DynamicModelChoiceField(
- queryset=Device.objects.all()
- )
- field_order = ('device', 'name_pattern', 'label_pattern')
+class ConsoleServerPortTemplateCreateForm(ComponentCreateForm, model_forms.ConsoleServerPortTemplateForm):
+ pass
-class FrontPortTemplateCreateForm(ModularComponentTemplateCreateForm):
+class PowerPortTemplateCreateForm(ComponentCreateForm, model_forms.PowerPortTemplateForm):
+ pass
+
+
+class PowerOutletTemplateCreateForm(ComponentCreateForm, model_forms.PowerOutletTemplateForm):
+ pass
+
+
+class InterfaceTemplateCreateForm(ComponentCreateForm, model_forms.InterfaceTemplateForm):
+ pass
+
+
+class FrontPortTemplateCreateForm(ComponentCreateForm, model_forms.FrontPortTemplateForm):
rear_port_set = forms.MultipleChoiceField(
choices=[],
label='Rear ports',
help_text='Select one rear port assignment for each front port being created.',
)
- field_order = (
- 'device_type', 'name_pattern', 'label_pattern', 'rear_port_set',
- )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -143,15 +148,56 @@ class FrontPortTemplateCreateForm(ModularComponentTemplateCreateForm):
}
-class FrontPortCreateForm(DeviceComponentCreateForm):
+class RearPortTemplateCreateForm(ComponentCreateForm, model_forms.RearPortTemplateForm):
+ pass
+
+
+class DeviceBayTemplateCreateForm(ComponentCreateForm, model_forms.DeviceBayTemplateForm):
+ pass
+
+
+class ModuleBayTemplateCreateForm(ComponentCreateForm, model_forms.ModuleBayTemplateForm):
+ position = ExpandableNameField(
+ label='Position',
+ required=False,
+ help_text='Alphanumeric ranges are supported. (Must match the number of names being created.)'
+ )
+
+
+class InventoryItemTemplateCreateForm(ComponentCreateForm, model_forms.InventoryItemTemplateForm):
+ pass
+
+
+#
+# Device components
+#
+
+class ConsolePortCreateForm(ComponentCreateForm, model_forms.ConsolePortForm):
+ pass
+
+
+class ConsoleServerPortCreateForm(ComponentCreateForm, model_forms.ConsoleServerPortForm):
+ pass
+
+
+class PowerPortCreateForm(ComponentCreateForm, model_forms.PowerPortForm):
+ pass
+
+
+class PowerOutletCreateForm(ComponentCreateForm, model_forms.PowerOutletForm):
+ pass
+
+
+class InterfaceCreateForm(ComponentCreateForm, model_forms.InterfaceForm):
+ pass
+
+
+class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm):
rear_port_set = forms.MultipleChoiceField(
choices=[],
label='Rear ports',
help_text='Select one rear port assignment for each front port being created.',
)
- field_order = (
- 'device', 'name_pattern', 'label_pattern', 'rear_port_set',
- )
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -189,22 +235,20 @@ class FrontPortCreateForm(DeviceComponentCreateForm):
}
-class ModuleBayTemplateCreateForm(ComponentTemplateCreateForm):
- position_pattern = ExpandableNameField(
+class RearPortCreateForm(ComponentCreateForm, model_forms.RearPortForm):
+ pass
+
+
+class DeviceBayCreateForm(ComponentCreateForm, model_forms.DeviceBayForm):
+ pass
+
+
+class ModuleBayCreateForm(ComponentCreateForm, model_forms.ModuleBayForm):
+ position = ExpandableNameField(
label='Position',
required=False,
help_text='Alphanumeric ranges are supported. (Must match the number of names being created.)'
)
- field_order = ('device_type', 'name_pattern', 'label_pattern', 'position_pattern')
-
-
-class ModuleBayCreateForm(DeviceComponentCreateForm):
- position_pattern = ExpandableNameField(
- label='Position',
- required=False,
- help_text='Alphanumeric ranges are supported. (Must match the number of names being created.)'
- )
- field_order = ('device', 'name_pattern', 'label_pattern', 'position_pattern')
class InventoryItemCreateForm(ComponentCreateForm):
@@ -212,6 +256,10 @@ class InventoryItemCreateForm(ComponentCreateForm):
field_order = ('name_pattern', 'label_pattern')
+#
+# Virtual chassis
+#
+
class VirtualChassisCreateForm(NetBoxModelForm):
region = DynamicModelChoiceField(
queryset=Region.objects.all(),
diff --git a/netbox/dcim/tests/test_forms.py b/netbox/dcim/tests/test_forms.py
index 53474314f..aad282725 100644
--- a/netbox/dcim/tests/test_forms.py
+++ b/netbox/dcim/tests/test_forms.py
@@ -132,7 +132,7 @@ class LabelTestCase(TestCase):
'name_pattern': 'eth[0-9]',
'label_pattern': 'Interface[0-9]',
}
- form = DeviceComponentCreateForm(interface_data)
+ form = InterfaceCreateForm(interface_data)
self.assertTrue(form.is_valid())
@@ -145,7 +145,7 @@ class LabelTestCase(TestCase):
'name_pattern': 'eth[0-9]',
'label_pattern': 'Interface[0-1]',
}
- form = DeviceComponentCreateForm(bad_interface_data)
+ form = InterfaceCreateForm(bad_interface_data)
self.assertFalse(form.is_valid())
self.assertIn('label_pattern', form.errors)
diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py
index 6ee74377a..a8f710efe 100644
--- a/netbox/dcim/views.py
+++ b/netbox/dcim/views.py
@@ -1120,9 +1120,8 @@ class ModuleTypeBulkDeleteView(generic.BulkDeleteView):
class ConsolePortTemplateCreateView(generic.ComponentCreateView):
queryset = ConsolePortTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.ConsolePortTemplateCreateForm
model_form = forms.ConsolePortTemplateForm
- template_name = 'dcim/component_template_create.html'
class ConsolePortTemplateEditView(generic.ObjectEditView):
@@ -1155,9 +1154,8 @@ class ConsolePortTemplateBulkDeleteView(generic.BulkDeleteView):
class ConsoleServerPortTemplateCreateView(generic.ComponentCreateView):
queryset = ConsoleServerPortTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.ConsoleServerPortTemplateCreateForm
model_form = forms.ConsoleServerPortTemplateForm
- template_name = 'dcim/component_template_create.html'
class ConsoleServerPortTemplateEditView(generic.ObjectEditView):
@@ -1190,9 +1188,8 @@ class ConsoleServerPortTemplateBulkDeleteView(generic.BulkDeleteView):
class PowerPortTemplateCreateView(generic.ComponentCreateView):
queryset = PowerPortTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.PowerPortTemplateCreateForm
model_form = forms.PowerPortTemplateForm
- template_name = 'dcim/component_template_create.html'
class PowerPortTemplateEditView(generic.ObjectEditView):
@@ -1225,9 +1222,8 @@ class PowerPortTemplateBulkDeleteView(generic.BulkDeleteView):
class PowerOutletTemplateCreateView(generic.ComponentCreateView):
queryset = PowerOutletTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.PowerOutletTemplateCreateForm
model_form = forms.PowerOutletTemplateForm
- template_name = 'dcim/component_template_create.html'
class PowerOutletTemplateEditView(generic.ObjectEditView):
@@ -1260,9 +1256,8 @@ class PowerOutletTemplateBulkDeleteView(generic.BulkDeleteView):
class InterfaceTemplateCreateView(generic.ComponentCreateView):
queryset = InterfaceTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.InterfaceTemplateCreateForm
model_form = forms.InterfaceTemplateForm
- template_name = 'dcim/component_template_create.html'
class InterfaceTemplateEditView(generic.ObjectEditView):
@@ -1297,15 +1292,6 @@ class FrontPortTemplateCreateView(generic.ComponentCreateView):
queryset = FrontPortTemplate.objects.all()
form = forms.FrontPortTemplateCreateForm
model_form = forms.FrontPortTemplateForm
- template_name = 'dcim/frontporttemplate_create.html'
-
- def initialize_forms(self, request):
- form, model_form = super().initialize_forms(request)
-
- model_form.fields.pop('rear_port')
- model_form.fields.pop('rear_port_position')
-
- return form, model_form
class FrontPortTemplateEditView(generic.ObjectEditView):
@@ -1338,9 +1324,8 @@ class FrontPortTemplateBulkDeleteView(generic.BulkDeleteView):
class RearPortTemplateCreateView(generic.ComponentCreateView):
queryset = RearPortTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.RearPortTemplateCreateForm
model_form = forms.RearPortTemplateForm
- template_name = 'dcim/component_template_create.html'
class RearPortTemplateEditView(generic.ObjectEditView):
@@ -1375,7 +1360,6 @@ class ModuleBayTemplateCreateView(generic.ComponentCreateView):
queryset = ModuleBayTemplate.objects.all()
form = forms.ModuleBayTemplateCreateForm
model_form = forms.ModuleBayTemplateForm
- template_name = 'dcim/modulebaytemplate_create.html'
patterned_fields = ('name', 'label', 'position')
@@ -1409,9 +1393,8 @@ class ModuleBayTemplateBulkDeleteView(generic.BulkDeleteView):
class DeviceBayTemplateCreateView(generic.ComponentCreateView):
queryset = DeviceBayTemplate.objects.all()
- form = forms.ComponentTemplateCreateForm
+ form = forms.DeviceBayTemplateCreateForm
model_form = forms.DeviceBayTemplateForm
- template_name = 'dcim/component_template_create.html'
class DeviceBayTemplateEditView(generic.ObjectEditView):
@@ -1444,9 +1427,8 @@ class DeviceBayTemplateBulkDeleteView(generic.BulkDeleteView):
class InventoryItemTemplateCreateView(generic.ComponentCreateView):
queryset = InventoryItemTemplate.objects.all()
- form = forms.ModularComponentTemplateCreateForm
+ form = forms.InventoryItemTemplateCreateForm
model_form = forms.InventoryItemTemplateForm
- template_name = 'dcim/inventoryitemtemplate_create.html'
def alter_object(self, instance, request):
# Set component (if any)
@@ -1874,7 +1856,7 @@ class ConsolePortView(generic.ObjectView):
class ConsolePortCreateView(generic.ComponentCreateView):
queryset = ConsolePort.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.ConsolePortCreateForm
model_form = forms.ConsolePortForm
@@ -1933,7 +1915,7 @@ class ConsoleServerPortView(generic.ObjectView):
class ConsoleServerPortCreateView(generic.ComponentCreateView):
queryset = ConsoleServerPort.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.ConsoleServerPortCreateForm
model_form = forms.ConsoleServerPortForm
@@ -1992,7 +1974,7 @@ class PowerPortView(generic.ObjectView):
class PowerPortCreateView(generic.ComponentCreateView):
queryset = PowerPort.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.PowerPortCreateForm
model_form = forms.PowerPortForm
@@ -2051,7 +2033,7 @@ class PowerOutletView(generic.ObjectView):
class PowerOutletCreateView(generic.ComponentCreateView):
queryset = PowerOutlet.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.PowerOutletCreateForm
model_form = forms.PowerOutletForm
@@ -2154,42 +2136,13 @@ class InterfaceView(generic.ObjectView):
class InterfaceCreateView(generic.ComponentCreateView):
queryset = Interface.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.InterfaceCreateForm
model_form = forms.InterfaceForm
- # template_name = 'dcim/interface_create.html'
-
- # TODO: Figure out what to do with this
- # def post(self, request):
- # """
- # Override inherited post() method to handle request to assign newly created
- # interface objects (first object) to an IP Address object.
- # """
- # form = self.form(request.POST, initial=request.GET)
- # new_objs = self.validate_form(request, form)
- #
- # if form.is_valid() and not form.errors:
- # if '_addanother' in request.POST:
- # return redirect(request.get_full_path())
- # elif new_objs is not None and '_assignip' in request.POST and len(new_objs) >= 1 and \
- # request.user.has_perm('ipam.add_ipaddress'):
- # first_obj = new_objs[0].pk
- # return redirect(
- # f'/ipam/ip-addresses/add/?interface={first_obj}&return_url={self.get_return_url(request)}'
- # )
- # else:
- # return redirect(self.get_return_url(request))
- #
- # return render(request, self.template_name, {
- # 'obj_type': self.queryset.model._meta.verbose_name,
- # 'form': form,
- # 'return_url': self.get_return_url(request),
- # })
class InterfaceEditView(generic.ObjectEditView):
queryset = Interface.objects.all()
form = forms.InterfaceForm
- template_name = 'dcim/interface_edit.html'
class InterfaceDeleteView(generic.ObjectDeleteView):
@@ -2244,14 +2197,6 @@ class FrontPortCreateView(generic.ComponentCreateView):
form = forms.FrontPortCreateForm
model_form = forms.FrontPortForm
- def initialize_forms(self, request):
- form, model_form = super().initialize_forms(request)
-
- model_form.fields.pop('rear_port')
- model_form.fields.pop('rear_port_position')
-
- return form, model_form
-
class FrontPortEditView(generic.ObjectEditView):
queryset = FrontPort.objects.all()
@@ -2308,7 +2253,7 @@ class RearPortView(generic.ObjectView):
class RearPortCreateView(generic.ComponentCreateView):
queryset = RearPort.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.RearPortCreateForm
model_form = forms.RearPortForm
@@ -2423,7 +2368,7 @@ class DeviceBayView(generic.ObjectView):
class DeviceBayCreateView(generic.ComponentCreateView):
queryset = DeviceBay.objects.all()
- form = forms.DeviceComponentCreateForm
+ form = forms.DeviceBayCreateForm
model_form = forms.DeviceBayForm
@@ -2552,7 +2497,6 @@ class InventoryItemCreateView(generic.ComponentCreateView):
queryset = InventoryItem.objects.all()
form = forms.InventoryItemCreateForm
model_form = forms.InventoryItemForm
- template_name = 'dcim/inventoryitem_create.html'
def alter_object(self, instance, request):
# Set component (if any)
diff --git a/netbox/netbox/views/generic/object_views.py b/netbox/netbox/views/generic/object_views.py
index 7617e0402..c69e04601 100644
--- a/netbox/netbox/views/generic/object_views.py
+++ b/netbox/netbox/views/generic/object_views.py
@@ -538,7 +538,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
"""
Add one or more components (e.g. interfaces, console ports, etc.) to a Device or VirtualMachine.
"""
- template_name = 'dcim/component_create.html'
+ template_name = 'generic/object_edit.html'
form = None
model_form = None
patterned_fields = ('name', 'label')
@@ -549,44 +549,38 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
def alter_object(self, instance, request):
return instance
- def initialize_forms(self, request):
+ def initialize_form(self, request):
data = request.POST if request.method == 'POST' else None
initial_data = normalize_querydict(request.GET)
- form = self.form(data=data, initial=request.GET)
- model_form = self.model_form(data=data, initial=initial_data)
+ form = self.form(data=data, initial=initial_data)
- # These fields will be set from the pattern values
- for field_name in self.patterned_fields:
- model_form.fields[field_name].widget = HiddenInput()
-
- return form, model_form
+ return form
def get(self, request):
- form, model_form = self.initialize_forms(request)
+ form = self.initialize_form(request)
instance = self.alter_object(self.queryset.model(), request)
return render(request, self.template_name, {
'object': instance,
- 'replication_form': form,
- 'form': model_form,
+ 'form': form,
'return_url': self.get_return_url(request),
})
def post(self, request):
logger = logging.getLogger('netbox.views.ComponentCreateView')
- form, model_form = self.initialize_forms(request)
+ form = self.initialize_form(request)
instance = self.alter_object(self.queryset.model(), request)
if form.is_valid():
new_components = []
data = deepcopy(request.POST)
- pattern_count = len(form.cleaned_data[f'{self.patterned_fields[0]}_pattern'])
+ pattern_count = len(form.cleaned_data[self.patterned_fields[0]])
for i in range(pattern_count):
for field_name in self.patterned_fields:
- if form.cleaned_data.get(f'{field_name}_pattern'):
- data[field_name] = form.cleaned_data[f'{field_name}_pattern'][i]
+ if form.cleaned_data.get(field_name):
+ data[field_name] = form.cleaned_data[field_name][i]
if hasattr(form, 'get_iterative_data'):
data.update(form.get_iterative_data(i))
@@ -626,7 +620,6 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
return render(request, self.template_name, {
'object': instance,
- 'replication_form': form,
- 'form': model_form,
+ 'form': form,
'return_url': self.get_return_url(request),
})
diff --git a/netbox/templates/dcim/component_template_create.html b/netbox/templates/dcim/component_template_create.html
deleted file mode 100644
index d164db872..000000000
--- a/netbox/templates/dcim/component_template_create.html
+++ /dev/null
@@ -1,38 +0,0 @@
-{% extends 'generic/object_edit.html' %}
-{% load form_helpers %}
-
-{% block form %}
- {% if form.module_type %}
-