mirror of
https://github.com/netbox-community/netbox.git
synced 2024-05-10 07:54:54 +00:00
Move component bulk creation views to new URLs
This commit is contained in:
@ -2180,6 +2180,10 @@ class ConsolePortForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class ConsolePortCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -2238,6 +2242,10 @@ class ConsoleServerPortForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class ConsoleServerPortCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -2331,6 +2339,10 @@ class PowerPortForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class PowerPortCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -2412,6 +2424,10 @@ class PowerOutletForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class PowerOutletCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -2437,11 +2453,12 @@ class PowerOutletCreateForm(ComponentForm):
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Limit power_port choices to those on the parent device
|
||||
self.fields['power_port'].queryset = PowerPort.objects.filter(device=self.parent)
|
||||
# Limit power_port queryset to PowerPorts which belong to the parent Device
|
||||
if 'device' in self.initial:
|
||||
device = Device.objects.filter(pk=self.initial['device']).first()
|
||||
self.fields['power_port'].queryset = PowerPort.objects.filter(device=device)
|
||||
|
||||
|
||||
class PowerOutletCSVForm(forms.ModelForm):
|
||||
@ -2631,7 +2648,8 @@ class InterfaceCreateForm(InterfaceCommonForm, ComponentForm, forms.Form):
|
||||
widget=StaticSelect2(),
|
||||
)
|
||||
enabled = forms.BooleanField(
|
||||
required=False
|
||||
required=False,
|
||||
initial=True
|
||||
)
|
||||
lag = forms.ModelChoiceField(
|
||||
queryset=Interface.objects.all(),
|
||||
@ -2686,21 +2704,15 @@ class InterfaceCreateForm(InterfaceCommonForm, ComponentForm, forms.Form):
|
||||
)
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
# Set interfaces enabled by default
|
||||
kwargs['initial'] = kwargs.get('initial', {}).copy()
|
||||
kwargs['initial'].update({'enabled': True})
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Limit LAG choices to interfaces belonging to this device (or its VC master)
|
||||
if self.parent is not None:
|
||||
# Limit LAG choices to interfaces which belong to the parent device (or VC master)
|
||||
if 'device' in self.initial:
|
||||
device = Device.objects.filter(pk=self.initial['device']).first()
|
||||
self.fields['lag'].queryset = Interface.objects.filter(
|
||||
device__in=[self.parent, self.parent.get_vc_master()],
|
||||
device__in=[device, device.get_vc_master()],
|
||||
type=InterfaceTypeChoices.TYPE_LAG
|
||||
)
|
||||
else:
|
||||
self.fields['lag'].queryset = Interface.objects.none()
|
||||
|
||||
|
||||
class InterfaceCSVForm(forms.ModelForm):
|
||||
@ -2917,6 +2929,10 @@ class FrontPortForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
# TODO: Merge with FrontPortTemplateCreateForm to remove duplicate logic
|
||||
class FrontPortCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -2936,15 +2952,17 @@ class FrontPortCreateForm(ComponentForm):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
parent = Device.objects.get(pk=self.initial['device'])
|
||||
|
||||
# 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.frontports.all()
|
||||
for front_port in parent.frontports.all()
|
||||
]
|
||||
|
||||
# Populate rear port choices
|
||||
choices = []
|
||||
rear_ports = RearPort.objects.filter(device=self.parent)
|
||||
rear_ports = RearPort.objects.filter(device=parent)
|
||||
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:
|
||||
@ -3084,6 +3102,10 @@ class RearPortForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class RearPortCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -3688,6 +3710,10 @@ class DeviceBayForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class DeviceBayCreateForm(ComponentForm):
|
||||
device = forms.ModelChoiceField(
|
||||
queryset=Device.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
|
@ -169,8 +169,8 @@ urlpatterns = [
|
||||
|
||||
# Console ports
|
||||
path(r'devices/console-ports/add/', views.DeviceBulkAddConsolePortView.as_view(), name='device_bulk_add_consoleport'),
|
||||
path(r'devices/<int:pk>/console-ports/add/', views.ConsolePortCreateView.as_view(), name='consoleport_add'),
|
||||
path(r'console-ports/', views.ConsolePortListView.as_view(), name='consoleport_list'),
|
||||
path(r'console-ports/add/', views.ConsolePortCreateView.as_view(), name='consoleport_add'),
|
||||
path(r'console-ports/import/', views.ConsolePortBulkImportView.as_view(), name='consoleport_import'),
|
||||
# TODO: Bulk edit view for ConsolePorts
|
||||
path(r'console-ports/delete/', views.ConsolePortBulkDeleteView.as_view(), name='consoleport_bulk_delete'),
|
||||
@ -181,10 +181,10 @@ urlpatterns = [
|
||||
|
||||
# Console server ports
|
||||
path(r'devices/console-server-ports/add/', views.DeviceBulkAddConsoleServerPortView.as_view(), name='device_bulk_add_consoleserverport'),
|
||||
path(r'devices/<int:pk>/console-server-ports/add/', views.ConsoleServerPortCreateView.as_view(), name='consoleserverport_add'),
|
||||
path(r'console-server-ports/', views.ConsoleServerPortListView.as_view(), name='consoleserverport_list'),
|
||||
path(r'console-server-ports/rename/', views.ConsoleServerPortBulkRenameView.as_view(), name='consoleserverport_bulk_rename'),
|
||||
path(r'console-server-ports/disconnect/', views.ConsoleServerPortBulkDisconnectView.as_view(), name='consoleserverport_bulk_disconnect'),
|
||||
path(r'console-server-ports/add/', views.ConsoleServerPortCreateView.as_view(), name='consoleserverport_add'),
|
||||
path(r'console-server-ports/import/', views.ConsoleServerPortBulkImportView.as_view(), name='consoleserverport_import'),
|
||||
path(r'console-server-ports/edit/', views.ConsoleServerPortBulkEditView.as_view(), name='consoleserverport_bulk_edit'),
|
||||
path(r'console-server-ports/delete/', views.ConsoleServerPortBulkDeleteView.as_view(), name='consoleserverport_bulk_delete'),
|
||||
@ -195,8 +195,8 @@ urlpatterns = [
|
||||
|
||||
# Power ports
|
||||
path(r'devices/power-ports/add/', views.DeviceBulkAddPowerPortView.as_view(), name='device_bulk_add_powerport'),
|
||||
path(r'devices/<int:pk>/power-ports/add/', views.PowerPortCreateView.as_view(), name='powerport_add'),
|
||||
path(r'power-ports/', views.PowerPortListView.as_view(), name='powerport_list'),
|
||||
path(r'power-ports/add/', views.PowerPortCreateView.as_view(), name='powerport_add'),
|
||||
path(r'power-ports/import/', views.PowerPortBulkImportView.as_view(), name='powerport_import'),
|
||||
# TODO: Bulk edit view for PowerPorts
|
||||
path(r'power-ports/delete/', views.PowerPortBulkDeleteView.as_view(), name='powerport_bulk_delete'),
|
||||
@ -207,10 +207,10 @@ urlpatterns = [
|
||||
|
||||
# Power outlets
|
||||
path(r'devices/power-outlets/add/', views.DeviceBulkAddPowerOutletView.as_view(), name='device_bulk_add_poweroutlet'),
|
||||
path(r'devices/<int:pk>/power-outlets/add/', views.PowerOutletCreateView.as_view(), name='poweroutlet_add'),
|
||||
path(r'power-outlets/', views.PowerOutletListView.as_view(), name='poweroutlet_list'),
|
||||
path(r'power-outlets/rename/', views.PowerOutletBulkRenameView.as_view(), name='poweroutlet_bulk_rename'),
|
||||
path(r'power-outlets/disconnect/', views.PowerOutletBulkDisconnectView.as_view(), name='poweroutlet_bulk_disconnect'),
|
||||
path(r'power-outlets/add/', views.PowerOutletCreateView.as_view(), name='poweroutlet_add'),
|
||||
path(r'power-outlets/import/', views.PowerOutletBulkImportView.as_view(), name='poweroutlet_import'),
|
||||
path(r'power-outlets/edit/', views.PowerOutletBulkEditView.as_view(), name='poweroutlet_bulk_edit'),
|
||||
path(r'power-outlets/delete/', views.PowerOutletBulkDeleteView.as_view(), name='poweroutlet_bulk_delete'),
|
||||
@ -221,10 +221,10 @@ urlpatterns = [
|
||||
|
||||
# Interfaces
|
||||
path(r'devices/interfaces/add/', views.DeviceBulkAddInterfaceView.as_view(), name='device_bulk_add_interface'),
|
||||
path(r'devices/<int:pk>/interfaces/add/', views.InterfaceCreateView.as_view(), name='interface_add'),
|
||||
path(r'interfaces/', views.InterfaceListView.as_view(), name='interface_list'),
|
||||
path(r'interfaces/rename/', views.InterfaceBulkRenameView.as_view(), name='interface_bulk_rename'),
|
||||
path(r'interfaces/disconnect/', views.InterfaceBulkDisconnectView.as_view(), name='interface_bulk_disconnect'),
|
||||
path(r'interfaces/add/', views.InterfaceCreateView.as_view(), name='interface_add'),
|
||||
path(r'interfaces/import/', views.InterfaceBulkImportView.as_view(), name='interface_import'),
|
||||
path(r'interfaces/edit/', views.InterfaceBulkEditView.as_view(), name='interface_bulk_edit'),
|
||||
path(r'interfaces/delete/', views.InterfaceBulkDeleteView.as_view(), name='interface_bulk_delete'),
|
||||
@ -237,10 +237,10 @@ urlpatterns = [
|
||||
|
||||
# Front ports
|
||||
# path(r'devices/front-ports/add/', views.DeviceBulkAddFrontPortView.as_view(), name='device_bulk_add_frontport'),
|
||||
path(r'devices/<int:pk>/front-ports/add/', views.FrontPortCreateView.as_view(), name='frontport_add'),
|
||||
path(r'front-ports/', views.FrontPortListView.as_view(), name='frontport_list'),
|
||||
path(r'front-ports/rename/', views.FrontPortBulkRenameView.as_view(), name='frontport_bulk_rename'),
|
||||
path(r'front-ports/disconnect/', views.FrontPortBulkDisconnectView.as_view(), name='frontport_bulk_disconnect'),
|
||||
path(r'front-ports/add/', views.FrontPortCreateView.as_view(), name='frontport_add'),
|
||||
path(r'front-ports/import/', views.FrontPortBulkImportView.as_view(), name='frontport_import'),
|
||||
path(r'front-ports/edit/', views.FrontPortBulkEditView.as_view(), name='frontport_bulk_edit'),
|
||||
path(r'front-ports/delete/', views.FrontPortBulkDeleteView.as_view(), name='frontport_bulk_delete'),
|
||||
@ -251,10 +251,10 @@ urlpatterns = [
|
||||
|
||||
# Rear ports
|
||||
# path(r'devices/rear-ports/add/', views.DeviceBulkAddRearPortView.as_view(), name='device_bulk_add_rearport'),
|
||||
path(r'devices/<int:pk>/rear-ports/add/', views.RearPortCreateView.as_view(), name='rearport_add'),
|
||||
path(r'rear-ports/', views.RearPortListView.as_view(), name='rearport_list'),
|
||||
path(r'rear-ports/rename/', views.RearPortBulkRenameView.as_view(), name='rearport_bulk_rename'),
|
||||
path(r'rear-ports/disconnect/', views.RearPortBulkDisconnectView.as_view(), name='rearport_bulk_disconnect'),
|
||||
path(r'rear-ports/add/', views.RearPortCreateView.as_view(), name='rearport_add'),
|
||||
path(r'rear-ports/import/', views.RearPortBulkImportView.as_view(), name='rearport_import'),
|
||||
path(r'rear-ports/edit/', views.RearPortBulkEditView.as_view(), name='rearport_bulk_edit'),
|
||||
path(r'rear-ports/delete/', views.RearPortBulkDeleteView.as_view(), name='rearport_bulk_delete'),
|
||||
@ -265,9 +265,9 @@ urlpatterns = [
|
||||
|
||||
# Device bays
|
||||
path(r'devices/device-bays/add/', views.DeviceBulkAddDeviceBayView.as_view(), name='device_bulk_add_devicebay'),
|
||||
path(r'devices/<int:pk>/bays/add/', views.DeviceBayCreateView.as_view(), name='devicebay_add'),
|
||||
path(r'device-bays/', views.DeviceBayListView.as_view(), name='devicebay_list'),
|
||||
path(r'device-bays/rename/', views.DeviceBayBulkRenameView.as_view(), name='devicebay_bulk_rename'),
|
||||
path(r'device-bays/add/', views.DeviceBayCreateView.as_view(), name='devicebay_add'),
|
||||
path(r'device-bays/import/', views.DeviceBayBulkImportView.as_view(), name='devicebay_import'),
|
||||
# TODO: Bulk edit view for DeviceBays
|
||||
path(r'device-bays/delete/', views.DeviceBayBulkDeleteView.as_view(), name='devicebay_bulk_delete'),
|
||||
@ -283,6 +283,7 @@ urlpatterns = [
|
||||
path(r'inventory-items/delete/', views.InventoryItemBulkDeleteView.as_view(), name='inventoryitem_bulk_delete'),
|
||||
path(r'inventory-items/<int:pk>/edit/', views.InventoryItemEditView.as_view(), name='inventoryitem_edit'),
|
||||
path(r'inventory-items/<int:pk>/delete/', views.InventoryItemDeleteView.as_view(), name='inventoryitem_delete'),
|
||||
# TODO: Replace below with InventoryItemCreateView
|
||||
path(r'devices/<int:device>/inventory-items/add/', views.InventoryItemEditView.as_view(), name='inventoryitem_add'),
|
||||
|
||||
# Cables
|
||||
|
@ -1205,8 +1205,6 @@ class ConsolePortListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class ConsolePortCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_consoleport'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = ConsolePort
|
||||
form = forms.ConsolePortCreateForm
|
||||
model_form = forms.ConsolePortForm
|
||||
@ -1253,8 +1251,6 @@ class ConsoleServerPortListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class ConsoleServerPortCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_consoleserverport'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = ConsoleServerPort
|
||||
form = forms.ConsoleServerPortCreateForm
|
||||
model_form = forms.ConsoleServerPortForm
|
||||
@ -1320,8 +1316,6 @@ class PowerPortListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class PowerPortCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_powerport'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = PowerPort
|
||||
form = forms.PowerPortCreateForm
|
||||
model_form = forms.PowerPortForm
|
||||
@ -1368,8 +1362,6 @@ class PowerOutletListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class PowerOutletCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_poweroutlet'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = PowerOutlet
|
||||
form = forms.PowerOutletCreateForm
|
||||
model_form = forms.PowerOutletForm
|
||||
@ -1471,8 +1463,6 @@ class InterfaceView(PermissionRequiredMixin, View):
|
||||
|
||||
class InterfaceCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_interface'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = Interface
|
||||
form = forms.InterfaceCreateForm
|
||||
model_form = forms.InterfaceForm
|
||||
@ -1539,8 +1529,6 @@ class FrontPortListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class FrontPortCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_frontport'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = FrontPort
|
||||
form = forms.FrontPortCreateForm
|
||||
model_form = forms.FrontPortForm
|
||||
@ -1606,8 +1594,6 @@ class RearPortListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class RearPortCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_rearport'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = RearPort
|
||||
form = forms.RearPortCreateForm
|
||||
model_form = forms.RearPortForm
|
||||
@ -1675,8 +1661,6 @@ class DeviceBayListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class DeviceBayCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_devicebay'
|
||||
parent_model = Device
|
||||
parent_field = 'device'
|
||||
model = DeviceBay
|
||||
form = forms.DeviceBayCreateForm
|
||||
model_form = forms.DeviceBayForm
|
||||
|
@ -48,14 +48,30 @@
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Components <span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu">
|
||||
{% if perms.dcim.add_consoleport %}<li><a href="{% url 'dcim:consoleport_add' pk=device.pk %}">Console Ports</a></li>{% endif %}
|
||||
{% if perms.dcim.add_consoleserverport %}<li><a href="{% url 'dcim:consoleserverport_add' pk=device.pk %}">Console Server Ports</a></li>{% endif %}
|
||||
{% if perms.dcim.add_powerport %}<li><a href="{% url 'dcim:powerport_add' pk=device.pk %}">Power Ports</a></li>{% endif %}
|
||||
{% if perms.dcim.add_poweroutlet %}<li><a href="{% url 'dcim:poweroutlet_add' pk=device.pk %}">Power Outlets</a></li>{% endif %}
|
||||
{% if perms.dcim.add_interface %}<li><a href="{% url 'dcim:interface_add' pk=device.pk %}">Interfaces</a></li>{% endif %}
|
||||
{% if perms.dcim.add_frontport %}<li><a href="{% url 'dcim:frontport_add' pk=device.pk %}">Front Ports</a></li>{% endif %}
|
||||
{% if perms.dcim.add_rearport %}<li><a href="{% url 'dcim:rearport_add' pk=device.pk %}">Rear Ports</a></li>{% endif %}
|
||||
{% if perms.dcim.add_devicebay %}<li><a href="{% url 'dcim:devicebay_add' pk=device.pk %}">Device Bays</a></li>{% endif %}
|
||||
{% if perms.dcim.add_consoleport %}
|
||||
<li><a href="{% url 'dcim:consoleport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Console Ports</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_consoleserverport %}
|
||||
<li><a href="{% url 'dcim:consoleserverport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Console Server Ports</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_powerport %}
|
||||
<li><a href="{% url 'dcim:powerport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Power Ports</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_poweroutlet %}
|
||||
<li><a href="{% url 'dcim:poweroutlet_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Power Outlets</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_interface %}
|
||||
<li><a href="{% url 'dcim:interface_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Interfaces</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_frontport %}
|
||||
<li><a href="{% url 'dcim:frontport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Front Ports</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_rearport %}
|
||||
<li><a href="{% url 'dcim:rearport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Rear Ports</a></li>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_devicebay %}
|
||||
<li><a href="{% url 'dcim:devicebay_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}">Device Bays</a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
@ -333,12 +349,12 @@
|
||||
{% if perms.dcim.add_interface or perms.dcim.add_consoleport or perms.dcim.add_powerport %}
|
||||
<div class="panel-footer text-right noprint">
|
||||
{% if perms.dcim.add_consoleport %}
|
||||
<a href="{% url 'dcim:consoleport_add' pk=device.pk %}" class="btn btn-xs btn-primary">
|
||||
<a href="{% url 'dcim:consoleport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-xs btn-primary">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add console port
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_powerport %}
|
||||
<a href="{% url 'dcim:powerport_add' pk=device.pk %}" class="btn btn-xs btn-primary">
|
||||
<a href="{% url 'dcim:powerport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-xs btn-primary">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add power port
|
||||
</a>
|
||||
{% endif %}
|
||||
@ -530,7 +546,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_devicebay %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'dcim:devicebay_add' pk=device.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'dcim:devicebay_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add device bays
|
||||
</a>
|
||||
</div>
|
||||
@ -603,7 +619,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_interface %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'dcim:interface_add' pk=device.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'dcim:interface_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add interfaces
|
||||
</a>
|
||||
</div>
|
||||
@ -664,7 +680,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_consoleserverport %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'dcim:consoleserverport_add' pk=device.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'dcim:consoleserverport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add console server ports
|
||||
</a>
|
||||
</div>
|
||||
@ -726,7 +742,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_poweroutlet %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'dcim:poweroutlet_add' pk=device.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'dcim:poweroutlet_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add power outlets
|
||||
</a>
|
||||
</div>
|
||||
@ -787,7 +803,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_frontport %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'dcim:frontport_add' pk=device.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'dcim:frontport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add front ports
|
||||
</a>
|
||||
</div>
|
||||
@ -845,7 +861,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_rearport %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'dcim:rearport_add' pk=device.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'dcim:rearport_add' %}?device={{ device.pk }}&return_url={{ device.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add rear ports
|
||||
</a>
|
||||
</div>
|
||||
|
@ -1,14 +1,11 @@
|
||||
{% extends '_base.html' %}
|
||||
{% load form_helpers %}
|
||||
|
||||
{% block title %}Create {{ component_type }} ({{ parent }}){% endblock %}
|
||||
{% block title %}Create {{ component_type }}{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="." method="post" class="form form-horizontal">
|
||||
<form action="" method="post" class="form form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% for field in form.hidden_fields %}
|
||||
{{ field }}
|
||||
{% endfor %}
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
{% if form.non_field_errors %}
|
||||
@ -27,7 +24,7 @@
|
||||
<div class="form-group">
|
||||
<label class="col-md-3 control-label required">Device</label>
|
||||
<div class="col-md-9">
|
||||
<p class="form-control-static">{{ parent }}</p>
|
||||
<p class="form-control-static">{{ form.device.value }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% render_form form %}
|
||||
|
@ -299,7 +299,7 @@
|
||||
{% endif %}
|
||||
{% if perms.dcim.add_interface %}
|
||||
<div class="pull-right">
|
||||
<a href="{% url 'virtualization:interface_add' pk=virtualmachine.pk %}" class="btn btn-primary btn-xs">
|
||||
<a href="{% url 'virtualization:interface_add' %}?virtual_machine={{ virtualmachine.pk }}&return_url={{ virtualmachine.get_absolute_url }}" class="btn btn-primary btn-xs">
|
||||
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add interfaces
|
||||
</a>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
{% block title %}Create {{ component_type }} ({{ parent }}){% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form action="." method="post" class="form form-horizontal">
|
||||
<form action="" method="post" class="form form-horizontal">
|
||||
{% csrf_token %}
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-md-offset-3">
|
||||
|
@ -727,14 +727,11 @@ class ConfirmationForm(BootstrapMixin, ReturnURLForm):
|
||||
confirm = forms.BooleanField(required=True, widget=forms.HiddenInput(), initial=True)
|
||||
|
||||
|
||||
# TODO: Remove ComponentForm
|
||||
class ComponentForm(BootstrapMixin, forms.Form):
|
||||
"""
|
||||
Allow inclusion of the parent Device/VirtualMachine as context for limiting field choices.
|
||||
"""
|
||||
def __init__(self, parent, *args, **kwargs):
|
||||
self.parent = parent
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
def get_iterative_data(self, iteration):
|
||||
return {}
|
||||
|
||||
|
@ -820,7 +820,8 @@ class BulkDeleteView(GetReturnURLMixin, View):
|
||||
# Device/VirtualMachine components
|
||||
#
|
||||
|
||||
class ComponentCreateView(View):
|
||||
# TODO: Replace with BulkCreateView
|
||||
class ComponentCreateView(GetReturnURLMixin, View):
|
||||
"""
|
||||
Add one or more components (e.g. interfaces, console ports, etc.) to a Device or VirtualMachine.
|
||||
"""
|
||||
@ -831,30 +832,23 @@ class ComponentCreateView(View):
|
||||
model_form = None
|
||||
template_name = None
|
||||
|
||||
def get(self, request, pk):
|
||||
def get(self, request):
|
||||
|
||||
parent = get_object_or_404(self.parent_model, pk=pk)
|
||||
data = deepcopy(request.GET)
|
||||
data[self.parent_field] = parent.pk
|
||||
form = self.form(parent, initial=data)
|
||||
form = self.form(initial=request.GET)
|
||||
|
||||
return render(request, self.template_name, {
|
||||
'parent': parent,
|
||||
'component_type': self.model._meta.verbose_name,
|
||||
'form': form,
|
||||
'return_url': parent.get_absolute_url(),
|
||||
'return_url': self.get_return_url(request),
|
||||
})
|
||||
|
||||
def post(self, request, pk):
|
||||
def post(self, request):
|
||||
|
||||
parent = get_object_or_404(self.parent_model, pk=pk)
|
||||
|
||||
form = self.form(parent, request.POST)
|
||||
form = self.form(request.POST, initial=request.GET)
|
||||
if form.is_valid():
|
||||
|
||||
new_components = []
|
||||
data = deepcopy(request.POST)
|
||||
data[self.parent_field] = parent.pk
|
||||
|
||||
for i, name in enumerate(form.cleaned_data['name_pattern']):
|
||||
|
||||
@ -879,19 +873,18 @@ class ComponentCreateView(View):
|
||||
for component_form in new_components:
|
||||
component_form.save()
|
||||
|
||||
messages.success(request, "Added {} {} to {}.".format(
|
||||
len(new_components), self.model._meta.verbose_name_plural, parent
|
||||
messages.success(request, "Added {} {}".format(
|
||||
len(new_components), self.model._meta.verbose_name_plural
|
||||
))
|
||||
if '_addanother' in request.POST:
|
||||
return redirect(request.path)
|
||||
return redirect(request.get_full_path())
|
||||
else:
|
||||
return redirect(parent.get_absolute_url())
|
||||
return redirect(self.get_return_url(request))
|
||||
|
||||
return render(request, self.template_name, {
|
||||
'parent': parent,
|
||||
'component_type': self.model._meta.verbose_name,
|
||||
'form': form,
|
||||
'return_url': parent.get_absolute_url(),
|
||||
'return_url': self.get_return_url(request),
|
||||
})
|
||||
|
||||
|
||||
|
@ -739,6 +739,10 @@ class InterfaceForm(BootstrapMixin, forms.ModelForm):
|
||||
|
||||
|
||||
class InterfaceCreateForm(ComponentForm):
|
||||
virtual_machine = forms.ModelChoiceField(
|
||||
queryset=VirtualMachine.objects.all(),
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
name_pattern = ExpandableNameField(
|
||||
label='Name'
|
||||
)
|
||||
@ -748,7 +752,8 @@ class InterfaceCreateForm(ComponentForm):
|
||||
widget=forms.HiddenInput()
|
||||
)
|
||||
enabled = forms.BooleanField(
|
||||
required=False
|
||||
required=False,
|
||||
initial=True
|
||||
)
|
||||
mtu = forms.IntegerField(
|
||||
required=False,
|
||||
@ -793,13 +798,9 @@ class InterfaceCreateForm(ComponentForm):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
# Set interfaces enabled by default
|
||||
kwargs['initial'] = kwargs.get('initial', {}).copy()
|
||||
kwargs['initial'].update({'enabled': True})
|
||||
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
# Limit VLan choices to those in: global vlans, global groups, the current site's group, the current site
|
||||
# Limit VLAN choices to those in: global vlans, global groups, the current site's group, the current site
|
||||
vlan_choices = []
|
||||
global_vlans = VLAN.objects.filter(site=None, group=None)
|
||||
vlan_choices.append(
|
||||
@ -811,7 +812,8 @@ class InterfaceCreateForm(ComponentForm):
|
||||
(group.name, [(vlan.pk, vlan) for vlan in global_group_vlans])
|
||||
)
|
||||
|
||||
site = getattr(self.parent.cluster, 'site', None)
|
||||
parent = VirtualMachine.objects.get(pk=self.initial['virtual_machine'])
|
||||
site = getattr(parent.cluster, 'site', None)
|
||||
if site is not None:
|
||||
|
||||
# Add non-grouped site VLANs
|
||||
|
@ -52,7 +52,7 @@ urlpatterns = [
|
||||
|
||||
# VM interfaces
|
||||
path(r'virtual-machines/interfaces/add/', views.VirtualMachineBulkAddInterfaceView.as_view(), name='virtualmachine_bulk_add_interface'),
|
||||
path(r'virtual-machines/<int:pk>/interfaces/add/', views.InterfaceCreateView.as_view(), name='interface_add'),
|
||||
path(r'interfaces/add/', views.InterfaceCreateView.as_view(), name='interface_add'),
|
||||
path(r'interfaces/edit/', views.InterfaceBulkEditView.as_view(), name='interface_bulk_edit'),
|
||||
path(r'interfaces/delete/', views.InterfaceBulkDeleteView.as_view(), name='interface_bulk_delete'),
|
||||
# TODO: Rename vm-interfaces to interfaces
|
||||
|
@ -330,8 +330,6 @@ class VirtualMachineBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class InterfaceCreateView(PermissionRequiredMixin, ComponentCreateView):
|
||||
permission_required = 'dcim.add_interface'
|
||||
parent_model = VirtualMachine
|
||||
parent_field = 'virtual_machine'
|
||||
model = Interface
|
||||
form = forms.InterfaceCreateForm
|
||||
model_form = forms.InterfaceForm
|
||||
|
Reference in New Issue
Block a user