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): class FrontPortForm(CustomFieldModelForm):
rear_port = DynamicModelChoiceField( rear_port = DynamicModelChoiceField(
queryset=RearPort.objects.all(), queryset=RearPort.objects.all(),
required=False,
query_params={ query_params={
'device_id': '$device', 'device_id': '$device',
} }

View File

@ -9,6 +9,8 @@ from utilities.forms import (
__all__ = ( __all__ = (
'ComponentCreateForm', 'ComponentCreateForm',
'FrontPortCreateForm',
'FrontPortTemplateCreateForm',
'VirtualChassisCreateForm', 'VirtualChassisCreateForm',
) )
@ -41,6 +43,97 @@ class ComponentCreateForm(BootstrapMixin, forms.Form):
}, code='label_pattern_mismatch') }, 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): class VirtualChassisCreateForm(CustomFieldModelForm):
region = DynamicModelChoiceField( region = DynamicModelChoiceField(
queryset=Region.objects.all(), queryset=Region.objects.all(),

View File

@ -1219,8 +1219,17 @@ class InterfaceTemplateBulkDeleteView(generic.BulkDeleteView):
class FrontPortTemplateCreateView(generic.ComponentCreateView): class FrontPortTemplateCreateView(generic.ComponentCreateView):
queryset = FrontPortTemplate.objects.all() queryset = FrontPortTemplate.objects.all()
form = forms.FrontPortTemplateCreateForm
model_form = forms.FrontPortTemplateForm 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): class FrontPortTemplateEditView(generic.ObjectEditView):
queryset = FrontPortTemplate.objects.all() queryset = FrontPortTemplate.objects.all()
@ -2085,8 +2094,17 @@ class FrontPortView(generic.ObjectView):
class FrontPortCreateView(generic.ComponentCreateView): class FrontPortCreateView(generic.ComponentCreateView):
queryset = FrontPort.objects.all() queryset = FrontPort.objects.all()
form = forms.FrontPortCreateForm
model_form = forms.FrontPortForm 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): class FrontPortEditView(generic.ObjectEditView):
queryset = FrontPort.objects.all() 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 Validate form values and set errors on the form object as they are detected. If
no errors are found, signal success messages. no errors are found, signal success messages.
""" """
logger = logging.getLogger('netbox.views.ComponentCreateView') logger = logging.getLogger('netbox.views.ComponentCreateView')
if form.is_valid(): if form.is_valid():
new_components = [] new_components = []
@ -749,8 +748,8 @@ class ComponentCreateView(GetReturnURLMixin, ObjectPermissionRequiredMixin, View
data['name'] = name data['name'] = name
data['label'] = label data['label'] = label
# if hasattr(form, 'get_iterative_data'): if hasattr(form, 'get_iterative_data'):
# data.update(form.get_iterative_data(i)) data.update(form.get_iterative_data(i))
component_form = self.model_form(data) component_form = self.model_form(data)

View File

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