Просмотр исходного кода

Clean up component template creation for ModuleTypes

jeremystretch 4 лет назад
Родитель
Сommit
bca0978434

+ 24 - 10
netbox/dcim/forms/object_create.py

@@ -8,9 +8,9 @@ from utilities.forms import (
 )
 )
 
 
 __all__ = (
 __all__ = (
-    'ComponentTemplateCreateForm',
+    'ModularComponentTemplateCreateForm',
     'DeviceComponentCreateForm',
     'DeviceComponentCreateForm',
-    'DeviceTypeComponentCreateForm',
+    'ComponentTemplateCreateForm',
     'FrontPortCreateForm',
     'FrontPortCreateForm',
     'FrontPortTemplateCreateForm',
     'FrontPortTemplateCreateForm',
     'VirtualChassisCreateForm',
     'VirtualChassisCreateForm',
@@ -45,14 +45,20 @@ class ComponentCreateForm(BootstrapMixin, forms.Form):
                 }, code='label_pattern_mismatch')
                 }, code='label_pattern_mismatch')
 
 
 
 
-class DeviceTypeComponentCreateForm(ComponentCreateForm):
+class ComponentTemplateCreateForm(ComponentCreateForm):
+    """
+    Creation form for component templates that can be assigned only to a DeviceType.
+    """
     device_type = DynamicModelChoiceField(
     device_type = DynamicModelChoiceField(
         queryset=DeviceType.objects.all(),
         queryset=DeviceType.objects.all(),
     )
     )
     field_order = ('device_type', 'name_pattern', 'label_pattern')
     field_order = ('device_type', 'name_pattern', 'label_pattern')
 
 
 
 
-class ComponentTemplateCreateForm(ComponentCreateForm):
+class ModularComponentTemplateCreateForm(ComponentCreateForm):
+    """
+    Creation form for component templates that can be assigned to either a DeviceType *or* a ModuleType.
+    """
     device_type = DynamicModelChoiceField(
     device_type = DynamicModelChoiceField(
         queryset=DeviceType.objects.all(),
         queryset=DeviceType.objects.all(),
         required=False
         required=False
@@ -71,7 +77,7 @@ class DeviceComponentCreateForm(ComponentCreateForm):
     field_order = ('device', 'name_pattern', 'label_pattern')
     field_order = ('device', 'name_pattern', 'label_pattern')
 
 
 
 
-class FrontPortTemplateCreateForm(DeviceTypeComponentCreateForm):
+class FrontPortTemplateCreateForm(ModularComponentTemplateCreateForm):
     rear_port_set = forms.MultipleChoiceField(
     rear_port_set = forms.MultipleChoiceField(
         choices=[],
         choices=[],
         label='Rear ports',
         label='Rear ports',
@@ -84,19 +90,27 @@ class FrontPortTemplateCreateForm(DeviceTypeComponentCreateForm):
     def __init__(self, *args, **kwargs):
     def __init__(self, *args, **kwargs):
         super().__init__(*args, **kwargs)
         super().__init__(*args, **kwargs)
 
 
-        device_type = DeviceType.objects.get(
-            pk=self.initial.get('device_type') or self.data.get('device_type')
-        )
+        # TODO: This needs better validation
+        if 'device_type' in self.initial or self.data.get('device_type'):
+            parent = DeviceType.objects.get(
+                pk=self.initial.get('device_type') or self.data.get('device_type')
+            )
+        elif 'module_type' in self.initial or self.data.get('module_type'):
+            parent = ModuleType.objects.get(
+                pk=self.initial.get('module_type') or self.data.get('module_type')
+            )
+        else:
+            return
 
 
         # Determine which rear port positions are occupied. These will be excluded from the list of available mappings.
         # Determine which rear port positions are occupied. These will be excluded from the list of available mappings.
         occupied_port_positions = [
         occupied_port_positions = [
             (front_port.rear_port_id, front_port.rear_port_position)
             (front_port.rear_port_id, front_port.rear_port_position)
-            for front_port in device_type.frontporttemplates.all()
+            for front_port in parent.frontporttemplates.all()
         ]
         ]
 
 
         # Populate rear port choices
         # Populate rear port choices
         choices = []
         choices = []
-        rear_ports = RearPortTemplate.objects.filter(device_type=device_type)
+        rear_ports = parent.rearporttemplates.all()
         for rear_port in rear_ports:
         for rear_port in rear_ports:
             for i in range(1, rear_port.positions + 1):
             for i in range(1, rear_port.positions + 1):
                 if (rear_port.pk, i) not in occupied_port_positions:
                 if (rear_port.pk, i) not in occupied_port_positions:

+ 37 - 17
netbox/dcim/views.py

@@ -50,23 +50,26 @@ class DeviceTypeComponentsView(DeviceComponentsView):
         return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)
         return self.child_model.objects.restrict(request.user, 'view').filter(device_type=parent)
 
 
     def get_extra_context(self, request, instance):
     def get_extra_context(self, request, instance):
-        if self.viewname:
-            return_url = reverse(self.viewname, kwargs={'pk': instance.pk})
-        else:
-            return_url = instance.get_absolute_url()
-        return {
-            'active_tab': f"{self.child_model._meta.verbose_name_plural.replace(' ', '-')}",
-            'return_url': return_url,
-        }
+        context = super().get_extra_context(request, instance)
+        context['return_url'] = reverse(self.viewname, kwargs={'pk': instance.pk})
+
+        return context
 
 
 
 
 class ModuleTypeComponentsView(DeviceComponentsView):
 class ModuleTypeComponentsView(DeviceComponentsView):
     queryset = ModuleType.objects.all()
     queryset = ModuleType.objects.all()
     template_name = 'dcim/moduletype/component_templates.html'
     template_name = 'dcim/moduletype/component_templates.html'
+    viewname = None  # Used for return_url resolution
 
 
     def get_children(self, request, parent):
     def get_children(self, request, parent):
         return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent)
         return self.child_model.objects.restrict(request.user, 'view').filter(module_type=parent)
 
 
+    def get_extra_context(self, request, instance):
+        context = super().get_extra_context(request, instance)
+        context['return_url'] = reverse(self.viewname, kwargs={'pk': instance.pk})
+
+        return context
+
 
 
 class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
 class BulkDisconnectView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View):
     """
     """
@@ -858,6 +861,7 @@ class DeviceTypeModuleBaysView(DeviceTypeComponentsView):
     child_model = ModuleBayTemplate
     child_model = ModuleBayTemplate
     table = tables.ModuleBayTemplateTable
     table = tables.ModuleBayTemplateTable
     filterset = filtersets.ModuleBayTemplateFilterSet
     filterset = filtersets.ModuleBayTemplateFilterSet
+    viewname = 'dcim:devicetype_modulebays'
 
 
 
 
 class DeviceTypeDeviceBaysView(DeviceTypeComponentsView):
 class DeviceTypeDeviceBaysView(DeviceTypeComponentsView):
@@ -962,42 +966,49 @@ class ModuleTypeConsolePortsView(ModuleTypeComponentsView):
     child_model = ConsolePortTemplate
     child_model = ConsolePortTemplate
     table = tables.ConsolePortTemplateTable
     table = tables.ConsolePortTemplateTable
     filterset = filtersets.ConsolePortTemplateFilterSet
     filterset = filtersets.ConsolePortTemplateFilterSet
+    viewname = 'dcim:moduletype_consoleports'
 
 
 
 
 class ModuleTypeConsoleServerPortsView(ModuleTypeComponentsView):
 class ModuleTypeConsoleServerPortsView(ModuleTypeComponentsView):
     child_model = ConsoleServerPortTemplate
     child_model = ConsoleServerPortTemplate
     table = tables.ConsoleServerPortTemplateTable
     table = tables.ConsoleServerPortTemplateTable
     filterset = filtersets.ConsoleServerPortTemplateFilterSet
     filterset = filtersets.ConsoleServerPortTemplateFilterSet
+    viewname = 'dcim:moduletype_consoleserverports'
 
 
 
 
 class ModuleTypePowerPortsView(ModuleTypeComponentsView):
 class ModuleTypePowerPortsView(ModuleTypeComponentsView):
     child_model = PowerPortTemplate
     child_model = PowerPortTemplate
     table = tables.PowerPortTemplateTable
     table = tables.PowerPortTemplateTable
     filterset = filtersets.PowerPortTemplateFilterSet
     filterset = filtersets.PowerPortTemplateFilterSet
+    viewname = 'dcim:moduletype_powerports'
 
 
 
 
 class ModuleTypePowerOutletsView(ModuleTypeComponentsView):
 class ModuleTypePowerOutletsView(ModuleTypeComponentsView):
     child_model = PowerOutletTemplate
     child_model = PowerOutletTemplate
     table = tables.PowerOutletTemplateTable
     table = tables.PowerOutletTemplateTable
     filterset = filtersets.PowerOutletTemplateFilterSet
     filterset = filtersets.PowerOutletTemplateFilterSet
+    viewname = 'dcim:moduletype_poweroutlets'
 
 
 
 
 class ModuleTypeInterfacesView(ModuleTypeComponentsView):
 class ModuleTypeInterfacesView(ModuleTypeComponentsView):
     child_model = InterfaceTemplate
     child_model = InterfaceTemplate
     table = tables.InterfaceTemplateTable
     table = tables.InterfaceTemplateTable
     filterset = filtersets.InterfaceTemplateFilterSet
     filterset = filtersets.InterfaceTemplateFilterSet
+    viewname = 'dcim:moduletype_interfaces'
 
 
 
 
 class ModuleTypeFrontPortsView(ModuleTypeComponentsView):
 class ModuleTypeFrontPortsView(ModuleTypeComponentsView):
     child_model = FrontPortTemplate
     child_model = FrontPortTemplate
     table = tables.FrontPortTemplateTable
     table = tables.FrontPortTemplateTable
     filterset = filtersets.FrontPortTemplateFilterSet
     filterset = filtersets.FrontPortTemplateFilterSet
+    viewname = 'dcim:moduletype_frontports'
 
 
 
 
 class ModuleTypeRearPortsView(ModuleTypeComponentsView):
 class ModuleTypeRearPortsView(ModuleTypeComponentsView):
     child_model = RearPortTemplate
     child_model = RearPortTemplate
     table = tables.RearPortTemplateTable
     table = tables.RearPortTemplateTable
     filterset = filtersets.RearPortTemplateFilterSet
     filterset = filtersets.RearPortTemplateFilterSet
+    viewname = 'dcim:moduletype_rearports'
 
 
 
 
 class ModuleTypeEditView(generic.ObjectEditView):
 class ModuleTypeEditView(generic.ObjectEditView):
@@ -1060,8 +1071,9 @@ class ModuleTypeBulkDeleteView(generic.BulkDeleteView):
 
 
 class ConsolePortTemplateCreateView(generic.ComponentCreateView):
 class ConsolePortTemplateCreateView(generic.ComponentCreateView):
     queryset = ConsolePortTemplate.objects.all()
     queryset = ConsolePortTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.ConsolePortTemplateForm
     model_form = forms.ConsolePortTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class ConsolePortTemplateEditView(generic.ObjectEditView):
 class ConsolePortTemplateEditView(generic.ObjectEditView):
@@ -1094,8 +1106,9 @@ class ConsolePortTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class ConsoleServerPortTemplateCreateView(generic.ComponentCreateView):
 class ConsoleServerPortTemplateCreateView(generic.ComponentCreateView):
     queryset = ConsoleServerPortTemplate.objects.all()
     queryset = ConsoleServerPortTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.ConsoleServerPortTemplateForm
     model_form = forms.ConsoleServerPortTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class ConsoleServerPortTemplateEditView(generic.ObjectEditView):
 class ConsoleServerPortTemplateEditView(generic.ObjectEditView):
@@ -1128,8 +1141,9 @@ class ConsoleServerPortTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class PowerPortTemplateCreateView(generic.ComponentCreateView):
 class PowerPortTemplateCreateView(generic.ComponentCreateView):
     queryset = PowerPortTemplate.objects.all()
     queryset = PowerPortTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.PowerPortTemplateForm
     model_form = forms.PowerPortTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class PowerPortTemplateEditView(generic.ObjectEditView):
 class PowerPortTemplateEditView(generic.ObjectEditView):
@@ -1162,8 +1176,9 @@ class PowerPortTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class PowerOutletTemplateCreateView(generic.ComponentCreateView):
 class PowerOutletTemplateCreateView(generic.ComponentCreateView):
     queryset = PowerOutletTemplate.objects.all()
     queryset = PowerOutletTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.PowerOutletTemplateForm
     model_form = forms.PowerOutletTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class PowerOutletTemplateEditView(generic.ObjectEditView):
 class PowerOutletTemplateEditView(generic.ObjectEditView):
@@ -1196,8 +1211,9 @@ class PowerOutletTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class InterfaceTemplateCreateView(generic.ComponentCreateView):
 class InterfaceTemplateCreateView(generic.ComponentCreateView):
     queryset = InterfaceTemplate.objects.all()
     queryset = InterfaceTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.InterfaceTemplateForm
     model_form = forms.InterfaceTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class InterfaceTemplateEditView(generic.ObjectEditView):
 class InterfaceTemplateEditView(generic.ObjectEditView):
@@ -1232,6 +1248,7 @@ class FrontPortTemplateCreateView(generic.ComponentCreateView):
     queryset = FrontPortTemplate.objects.all()
     queryset = FrontPortTemplate.objects.all()
     form = forms.FrontPortTemplateCreateForm
     form = forms.FrontPortTemplateCreateForm
     model_form = forms.FrontPortTemplateForm
     model_form = forms.FrontPortTemplateForm
+    template_name = 'dcim/frontporttemplate_create.html'
 
 
     def initialize_forms(self, request):
     def initialize_forms(self, request):
         form, model_form = super().initialize_forms(request)
         form, model_form = super().initialize_forms(request)
@@ -1272,8 +1289,9 @@ class FrontPortTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class RearPortTemplateCreateView(generic.ComponentCreateView):
 class RearPortTemplateCreateView(generic.ComponentCreateView):
     queryset = RearPortTemplate.objects.all()
     queryset = RearPortTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.RearPortTemplateForm
     model_form = forms.RearPortTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class RearPortTemplateEditView(generic.ObjectEditView):
 class RearPortTemplateEditView(generic.ObjectEditView):
@@ -1306,8 +1324,9 @@ class RearPortTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class ModuleBayTemplateCreateView(generic.ComponentCreateView):
 class ModuleBayTemplateCreateView(generic.ComponentCreateView):
     queryset = ModuleBayTemplate.objects.all()
     queryset = ModuleBayTemplate.objects.all()
-    form = forms.DeviceTypeComponentCreateForm
+    form = forms.ComponentTemplateCreateForm
     model_form = forms.ModuleBayTemplateForm
     model_form = forms.ModuleBayTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class ModuleBayTemplateEditView(generic.ObjectEditView):
 class ModuleBayTemplateEditView(generic.ObjectEditView):
@@ -1340,8 +1359,9 @@ class ModuleBayTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class DeviceBayTemplateCreateView(generic.ComponentCreateView):
 class DeviceBayTemplateCreateView(generic.ComponentCreateView):
     queryset = DeviceBayTemplate.objects.all()
     queryset = DeviceBayTemplate.objects.all()
-    form = forms.DeviceTypeComponentCreateForm
+    form = forms.ComponentTemplateCreateForm
     model_form = forms.DeviceBayTemplateForm
     model_form = forms.DeviceBayTemplateForm
+    template_name = 'dcim/component_template_create.html'
 
 
 
 
 class DeviceBayTemplateEditView(generic.ObjectEditView):
 class DeviceBayTemplateEditView(generic.ObjectEditView):
@@ -1374,7 +1394,7 @@ class DeviceBayTemplateBulkDeleteView(generic.BulkDeleteView):
 
 
 class InventoryItemTemplateCreateView(generic.ComponentCreateView):
 class InventoryItemTemplateCreateView(generic.ComponentCreateView):
     queryset = InventoryItemTemplate.objects.all()
     queryset = InventoryItemTemplate.objects.all()
-    form = forms.ComponentTemplateCreateForm
+    form = forms.ModularComponentTemplateCreateForm
     model_form = forms.InventoryItemTemplateForm
     model_form = forms.InventoryItemTemplateForm
     template_name = 'dcim/inventoryitem_create.html'
     template_name = 'dcim/inventoryitem_create.html'
 
 

+ 34 - 0
netbox/templates/dcim/component_template_create.html

@@ -0,0 +1,34 @@
+{% extends 'generic/object_edit.html' %}
+{% load form_helpers %}
+
+{% block form %}
+  <div class="row mb-2">
+    <div class="offset-sm-3">
+      <ul class="nav nav-pills" role="tablist">
+        <li role="presentation" class="nav-item">
+          <button role="tab" type="button" id="devicetype_tab" data-bs-toggle="tab" aria-controls="devicetype" data-bs-target="#devicetype" class="nav-link {% if not form.initial.module_type %}active{% endif %}">
+            Device Type
+          </button>
+        </li>
+        <li role="presentation" class="nav-item">
+          <button role="tab" type="button" id="moduletype_tab" data-bs-toggle="tab" aria-controls="moduletype" data-bs-target="#moduletype" class="nav-link {% if form.initial.module_type %}active{% endif %}">
+            Module Type
+          </button>
+        </li>
+      </ul>
+    </div>
+  </div>
+  <div class="tab-content p-0 border-0">
+    <div class="tab-pane {% if not form.initial.module_type %}active{% endif %}" id="devicetype" role="tabpanel">
+      {% render_field replication_form.device_type %}
+    </div>
+    <div class="tab-pane {% if form.initial.module_type %}active{% endif %}" id="moduletype" role="tabpanel">
+      {% render_field replication_form.module_type %}
+    </div>
+    {% block replication_fields %}
+      {% render_field replication_form.name_pattern %}
+      {% render_field replication_form.label_pattern %}
+    {% endblock replication_fields %}
+  </div>
+  {{ block.super }}
+{% endblock form %}

+ 7 - 0
netbox/templates/dcim/frontporttemplate_create.html

@@ -0,0 +1,7 @@
+{% extends 'dcim/component_template_create.html' %}
+{% load form_helpers %}
+
+{% block replication_fields %}
+  {{ block.super }}
+  {% render_field replication_form.rear_port_set %}
+{% endblock replication_fields %}

+ 4 - 5
netbox/templates/dcim/inventoryitem_create.html

@@ -1,9 +1,9 @@
-{% extends 'generic/object_edit.html' %}
+{% extends 'dcim/component_template_create.html' %}
 {% load helpers %}
 {% load helpers %}
 {% load form_helpers %}
 {% load form_helpers %}
 
 
-{% block form %}
-  {% render_form replication_form %}
+{% block replication_fields %}
+  {{ block.super }}
   {% if object.component %}
   {% if object.component %}
     <div class="row mb-3">
     <div class="row mb-3">
         <label class="col-sm-3 col-form-label text-lg-end">
         <label class="col-sm-3 col-form-label text-lg-end">
@@ -14,5 +14,4 @@
         </div>
         </div>
     </div>
     </div>
   {% endif %}
   {% endif %}
-  {{ block.super }}
-{% endblock %}
+{% endblock replication_fields %}