diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index c7cee68f7..0b303d663 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -1043,11 +1043,17 @@ class ConsolePortTemplateForm(BootstrapMixin, forms.ModelForm): class ConsolePortTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) type = forms.ChoiceField( - choices=ConsolePortTypeChoices, + choices=add_blank_choice(ConsolePortTypeChoices), widget=StaticSelect2() ) @@ -1065,6 +1071,12 @@ class ConsoleServerPortTemplateForm(BootstrapMixin, forms.ModelForm): class ConsoleServerPortTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) @@ -1087,6 +1099,12 @@ class PowerPortTemplateForm(BootstrapMixin, forms.ModelForm): class PowerPortTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) @@ -1129,6 +1147,12 @@ class PowerOutletTemplateForm(BootstrapMixin, forms.ModelForm): class PowerOutletTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) @@ -1147,12 +1171,11 @@ class PowerOutletTemplateCreateForm(BootstrapMixin, forms.Form): ) def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) # Limit power_port choices to current DeviceType self.fields['power_port'].queryset = PowerPortTemplate.objects.filter( - device_type=self.parent + device_type=self.initial.get('device_type') ) @@ -1170,6 +1193,12 @@ class InterfaceTemplateForm(BootstrapMixin, forms.ModelForm): class InterfaceTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) @@ -1227,6 +1256,12 @@ class FrontPortTemplateForm(BootstrapMixin, forms.ModelForm): class FrontPortTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) @@ -1241,18 +1276,19 @@ class FrontPortTemplateCreateForm(BootstrapMixin, forms.Form): ) def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) + device_type = DeviceType.objects.filter(pk=self.initial.get('device_type')).first() + # Determine which rear port positions are occupied. These will be excluded from the list of available mappings. occupied_port_positions = [ (front_port.rear_port_id, front_port.rear_port_position) - for front_port in self.parent.frontport_templates.all() + for front_port in device_type.frontport_templates.all() ] # Populate rear port choices choices = [] - rear_ports = RearPortTemplate.objects.filter(device_type=self.parent) + rear_ports = RearPortTemplate.objects.filter(device_type=device_type) for rear_port in rear_ports: for i in range(1, rear_port.positions + 1): if (rear_port.pk, i) not in occupied_port_positions: @@ -1297,6 +1333,12 @@ class RearPortTemplateForm(BootstrapMixin, forms.ModelForm): class RearPortTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) @@ -1325,6 +1367,12 @@ class DeviceBayTemplateForm(BootstrapMixin, forms.ModelForm): class DeviceBayTemplateCreateForm(BootstrapMixin, forms.Form): + device_type = forms.ModelChoiceField( + queryset=DeviceType.objects.all(), + widget=APISelect( + api_url='/api/dcim/device-types/' + ) + ) name_pattern = ExpandableNameField( label='Name' ) diff --git a/netbox/dcim/urls.py b/netbox/dcim/urls.py index 25c2b3525..f73ccef09 100644 --- a/netbox/dcim/urls.py +++ b/netbox/dcim/urls.py @@ -91,43 +91,43 @@ urlpatterns = [ path('device-types//changelog/', ObjectChangeLogView.as_view(), name='devicetype_changelog', kwargs={'model': DeviceType}), # Console port templates - path('device-types//console-ports/add/', views.ConsolePortTemplateCreateView.as_view(), name='devicetype_add_consoleport'), + path('console-port-templates/add/', views.ConsolePortTemplateCreateView.as_view(), name='consoleporttemplate_add'), path('console-port-templates/delete/', views.ConsolePortTemplateBulkDeleteView.as_view(), name='consoleporttemplate_bulk_delete'), path('console-port-templates//edit/', views.ConsolePortTemplateEditView.as_view(), name='consoleporttemplate_edit'), # Console server port templates - path('device-types//console-server-ports/add/', views.ConsoleServerPortTemplateCreateView.as_view(), name='devicetype_add_consoleserverport'), + path('console-server-port-templates/add/', views.ConsoleServerPortTemplateCreateView.as_view(), name='consoleserverporttemplate_add'), path('console-server-port-templates/delete/', views.ConsoleServerPortTemplateBulkDeleteView.as_view(), name='consoleserverporttemplate_bulk_delete'), path('console-server-port-templates//edit/', views.ConsoleServerPortTemplateEditView.as_view(), name='consoleserverporttemplate_edit'), # Power port templates - path('device-types//power-ports/add/', views.PowerPortTemplateCreateView.as_view(), name='devicetype_add_powerport'), + path('power-port-templates/add/', views.PowerPortTemplateCreateView.as_view(), name='powerporttemplate_add'), path('power-port-templates/delete/', views.PowerPortTemplateBulkDeleteView.as_view(), name='powerporttemplate_bulk_delete'), path('power-port-templates//edit/', views.PowerPortTemplateEditView.as_view(), name='powerporttemplate_edit'), # Power outlet templates - path('device-types//power-outlets/add/', views.PowerOutletTemplateCreateView.as_view(), name='devicetype_add_poweroutlet'), + path('power-outlet-templates/add/', views.PowerOutletTemplateCreateView.as_view(), name='poweroutlettemplate_add'), path('power-outlet-templates/delete/', views.PowerOutletTemplateBulkDeleteView.as_view(), name='poweroutlettemplate_bulk_delete'), path('power-outlet-templates//edit/', views.PowerOutletTemplateEditView.as_view(), name='poweroutlettemplate_edit'), # Interface templates - path('device-types//interfaces/add/', views.InterfaceTemplateCreateView.as_view(), name='devicetype_add_interface'), + path('interface-templates/add/', views.InterfaceTemplateCreateView.as_view(), name='interfacetemplate_add'), path('interface-templates/edit/', views.InterfaceTemplateBulkEditView.as_view(), name='interfacetemplate_bulk_edit'), path('interface-templates/delete/', views.InterfaceTemplateBulkDeleteView.as_view(), name='interfacetemplate_bulk_delete'), path('interface-templates//edit/', views.InterfaceTemplateEditView.as_view(), name='interfacetemplate_edit'), # Front port templates - path('device-types//front-ports/add/', views.FrontPortTemplateCreateView.as_view(), name='devicetype_add_frontport'), + path('front-port-templates/add/', views.FrontPortTemplateCreateView.as_view(), name='frontporttemplate_add'), path('front-port-templates/delete/', views.FrontPortTemplateBulkDeleteView.as_view(), name='frontporttemplate_bulk_delete'), path('front-port-templates//edit/', views.FrontPortTemplateEditView.as_view(), name='frontporttemplate_edit'), # Rear port templates - path('device-types//rear-ports/add/', views.RearPortTemplateCreateView.as_view(), name='devicetype_add_rearport'), + path('rear-port-templates/add/', views.RearPortTemplateCreateView.as_view(), name='rearporttemplate_add'), path('rear-port-templates/delete/', views.RearPortTemplateBulkDeleteView.as_view(), name='rearporttemplate_bulk_delete'), path('rear-port-templates//edit/', views.RearPortTemplateEditView.as_view(), name='rearporttemplate_edit'), # Device bay templates - path('device-types//device-bays/add/', views.DeviceBayTemplateCreateView.as_view(), name='devicetype_add_devicebay'), + path('device-bay-templates/add/', views.DeviceBayTemplateCreateView.as_view(), name='devicebaytemplate_add'), path('device-bay-templates/delete/', views.DeviceBayTemplateBulkDeleteView.as_view(), name='devicebaytemplate_bulk_delete'), path('device-bay-templates//edit/', views.DeviceBayTemplateEditView.as_view(), name='devicebaytemplate_edit'), diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index 2ba3557da..22ba08f85 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -705,8 +705,6 @@ class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): class ConsolePortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_consoleporttemplate' - parent_model = DeviceType - parent_field = 'device_type' model = ConsolePortTemplate form = forms.ConsolePortTemplateCreateForm model_form = forms.ConsolePortTemplateForm @@ -727,8 +725,6 @@ class ConsolePortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView) class ConsoleServerPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_consoleserverporttemplate' - parent_model = DeviceType - parent_field = 'device_type' model = ConsoleServerPortTemplate form = forms.ConsoleServerPortTemplateCreateForm model_form = forms.ConsoleServerPortTemplateForm @@ -749,8 +745,6 @@ class ConsoleServerPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDelet class PowerPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_powerporttemplate' - parent_model = DeviceType - parent_field = 'device_type' model = PowerPortTemplate form = forms.PowerPortTemplateCreateForm model_form = forms.PowerPortTemplateForm @@ -771,8 +765,6 @@ class PowerPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): class PowerOutletTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_poweroutlettemplate' - parent_model = DeviceType - parent_field = 'device_type' model = PowerOutletTemplate form = forms.PowerOutletTemplateCreateForm model_form = forms.PowerOutletTemplateForm @@ -793,8 +785,6 @@ class PowerOutletTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView) class InterfaceTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_interfacetemplate' - parent_model = DeviceType - parent_field = 'device_type' model = InterfaceTemplate form = forms.InterfaceTemplateCreateForm model_form = forms.InterfaceTemplateForm @@ -822,8 +812,6 @@ class InterfaceTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): class FrontPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_frontporttemplate' - parent_model = DeviceType - parent_field = 'device_type' model = FrontPortTemplate form = forms.FrontPortTemplateCreateForm model_form = forms.FrontPortTemplateForm @@ -844,8 +832,6 @@ class FrontPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): class RearPortTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_rearporttemplate' - parent_model = DeviceType - parent_field = 'device_type' model = RearPortTemplate form = forms.RearPortTemplateCreateForm model_form = forms.RearPortTemplateForm @@ -866,8 +852,6 @@ class RearPortTemplateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): class DeviceBayTemplateCreateView(PermissionRequiredMixin, ComponentCreateView): permission_required = 'dcim.add_devicebaytemplate' - parent_model = DeviceType - parent_field = 'device_type' model = DeviceBayTemplate form = forms.DeviceBayTemplateCreateForm model_form = forms.DeviceBayTemplateForm diff --git a/netbox/templates/dcim/devicetype.html b/netbox/templates/dcim/devicetype.html index 9c0419043..5e3e07252 100644 --- a/netbox/templates/dcim/devicetype.html +++ b/netbox/templates/dcim/devicetype.html @@ -22,14 +22,14 @@ Add Components {% endif %} @@ -136,48 +136,48 @@ {% if devicetype.consoleport_templates.exists or devicetype.powerport_templates.exists %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=consoleport_table title='Console Ports' add_url='dcim:devicetype_add_consoleport' delete_url='dcim:consoleporttemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=consoleport_table title='Console Ports' add_url='dcim:consoleporttemplate_add' delete_url='dcim:consoleporttemplate_bulk_delete' %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=powerport_table title='Power Ports' add_url='dcim:devicetype_add_powerport' delete_url='dcim:powerporttemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=powerport_table title='Power Ports' add_url='dcim:powerporttemplate_add' delete_url='dcim:powerporttemplate_bulk_delete' %}
{% endif %} {% if devicetype.is_parent_device or devicebay_table.rows %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=devicebay_table title='Device Bays' add_url='dcim:devicetype_add_devicebay' delete_url='dcim:devicebaytemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=devicebay_table title='Device Bays' add_url='dcim:devicebaytemplate_add' delete_url='dcim:devicebaytemplate_bulk_delete' %}
{% endif %} {% if devicetype.consoleserverport_templates.exists %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=consoleserverport_table title='Console Server Ports' add_url='dcim:devicetype_add_consoleserverport' delete_url='dcim:consoleserverporttemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=consoleserverport_table title='Console Server Ports' add_url='dcim:consoleserverporttemplate_add' delete_url='dcim:consoleserverporttemplate_bulk_delete' %}
{% endif %} {% if devicetype.poweroutlet_templates.exists %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=poweroutlet_table title='Power Outlets' add_url='dcim:devicetype_add_poweroutlet' delete_url='dcim:poweroutlettemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=poweroutlet_table title='Power Outlets' add_url='dcim:poweroutlettemplate_add' delete_url='dcim:poweroutlettemplate_bulk_delete' %}
{% endif %} {% if devicetype.interface_templates.exists %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=interface_table title='Interfaces' add_url='dcim:devicetype_add_interface' edit_url='dcim:interfacetemplate_bulk_edit' delete_url='dcim:interfacetemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=interface_table title='Interfaces' add_url='dcim:interfacetemplate_add' edit_url='dcim:interfacetemplate_bulk_edit' delete_url='dcim:interfacetemplate_bulk_delete' %}
{% endif %} {% if devicetype.frontport_templates.exists or devicetype.rearport_templates.exists %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=front_port_table title='Front Ports' add_url='dcim:devicetype_add_frontport' delete_url='dcim:frontporttemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=front_port_table title='Front Ports' add_url='dcim:frontporttemplate_add' delete_url='dcim:frontporttemplate_bulk_delete' %}
- {% include 'dcim/inc/devicetype_component_table.html' with table=rear_port_table title='Rear Ports' add_url='dcim:devicetype_add_rearport' delete_url='dcim:rearporttemplate_bulk_delete' %} + {% include 'dcim/inc/devicetype_component_table.html' with table=rear_port_table title='Rear Ports' add_url='dcim:rearporttemplate_add' delete_url='dcim:rearporttemplate_bulk_delete' %}
{% endif %} diff --git a/netbox/templates/dcim/inc/devicetype_component_table.html b/netbox/templates/dcim/inc/devicetype_component_table.html index 0fbf2c246..6e81e65b8 100644 --- a/netbox/templates/dcim/inc/devicetype_component_table.html +++ b/netbox/templates/dcim/inc/devicetype_component_table.html @@ -20,7 +20,7 @@ {% endif %} {% endif %}
- + Add {{ title }} diff --git a/netbox/utilities/views.py b/netbox/utilities/views.py index 7c7ea9eb5..7c38aceee 100644 --- a/netbox/utilities/views.py +++ b/netbox/utilities/views.py @@ -825,8 +825,6 @@ class ComponentCreateView(GetReturnURLMixin, View): """ Add one or more components (e.g. interfaces, console ports, etc.) to a Device or VirtualMachine. """ - parent_model = None - parent_field = None model = None form = None model_form = None