Restore front port component creation

This commit is contained in:
jeremystretch 2021-12-28 09:53:56 -05:00
parent 8ca09ec07f
commit 4075cc8518
5 changed files with 118 additions and 7 deletions

View File

@ -1267,7 +1267,6 @@ class InterfaceForm(InterfaceCommonForm, CustomFieldModelForm):
class FrontPortForm(CustomFieldModelForm):
rear_port = DynamicModelChoiceField(
queryset=RearPort.objects.all(),
required=False,
query_params={
'device_id': '$device',
}

View File

@ -9,6 +9,8 @@ from utilities.forms import (
__all__ = (
'ComponentCreateForm',
'FrontPortCreateForm',
'FrontPortTemplateCreateForm',
'VirtualChassisCreateForm',
)
@ -41,6 +43,97 @@ class ComponentCreateForm(BootstrapMixin, forms.Form):
}, code='label_pattern_mismatch')
class FrontPortTemplateCreateForm(ComponentCreateForm):
rear_port_set = forms.MultipleChoiceField(
choices=[],
label='Rear ports',
help_text='Select one rear port assignment for each front port being created.',
)
field_order = (
'name_pattern', 'label_pattern', 'rear_port_set',
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
device_type = DeviceType.objects.get(
pk=self.initial.get('device_type') or self.data.get('device_type')
)
# 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 device_type.frontporttemplates.all()
]
# Populate rear port choices
choices = []
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:
choices.append(
('{}:{}'.format(rear_port.pk, i), '{}:{}'.format(rear_port.name, i))
)
self.fields['rear_port_set'].choices = choices
def get_iterative_data(self, iteration):
# Assign rear port and position from selected set
rear_port, position = self.cleaned_data['rear_port_set'][iteration].split(':')
return {
'rear_port': int(rear_port),
'rear_port_position': int(position),
}
class FrontPortCreateForm(ComponentCreateForm):
rear_port_set = forms.MultipleChoiceField(
choices=[],
label='Rear ports',
help_text='Select one rear port assignment for each front port being created.',
)
field_order = (
'name_pattern', 'label_pattern', 'rear_port_set',
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
device = Device.objects.get(
pk=self.initial.get('device') or self.data.get('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 device.frontports.all()
]
# Populate rear port choices
choices = []
rear_ports = RearPort.objects.filter(device=device)
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:
choices.append(
('{}:{}'.format(rear_port.pk, i), '{}:{}'.format(rear_port.name, i))
)
self.fields['rear_port_set'].choices = choices
def get_iterative_data(self, iteration):
# Assign rear port and position from selected set
rear_port, position = self.cleaned_data['rear_port_set'][iteration].split(':')
return {
'rear_port': int(rear_port),
'rear_port_position': int(position),
}
class VirtualChassisCreateForm(CustomFieldModelForm):
region = DynamicModelChoiceField(
queryset=Region.objects.all(),

View File

@ -1219,8 +1219,17 @@ class InterfaceTemplateBulkDeleteView(generic.BulkDeleteView):
class FrontPortTemplateCreateView(generic.ComponentCreateView):
queryset = FrontPortTemplate.objects.all()
form = forms.FrontPortTemplateCreateForm
model_form = forms.FrontPortTemplateForm
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):
queryset = FrontPortTemplate.objects.all()
@ -2085,8 +2094,17 @@ class FrontPortView(generic.ObjectView):
class FrontPortCreateView(generic.ComponentCreateView):
queryset = FrontPort.objects.all()
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()

View File

@ -735,7 +735,6 @@ class ComponentCreateView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View
Validate form values and set errors on the form object as they are detected. If
no errors are found, signal success messages.
"""
logger = logging.getLogger('netbox.views.ComponentCreateView')
if form.is_valid():
new_components = []
@ -749,8 +748,8 @@ class ComponentCreateView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View
data['name'] = name
data['label'] = label
# if hasattr(form, 'get_iterative_data'):
# data.update(form.get_iterative_data(i))
if hasattr(form, 'get_iterative_data'):
data.update(form.get_iterative_data(i))
component_form = self.model_form(data)

View File

@ -31,13 +31,15 @@
<form action="" method="post" enctype="multipart/form-data" class="form-object-edit">
{% csrf_token %}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
{% block form %}
{% if form.Meta.fieldsets %}
{# Render hidden fields #}
{% for field in form.hidden_fields %}
{{ field }}
{% endfor %}
{# Render grouped fields according to Form #}
{% for group, fields in form.Meta.fieldsets %}
<div class="field-group mb-5">