mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-19 20:02:22 -06:00
Fix FrontPortCreateForm
This commit is contained in:
@@ -1617,6 +1617,7 @@ class FrontPortForm(ModularDeviceComponentForm):
|
|||||||
]
|
]
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
|
super().clean()
|
||||||
|
|
||||||
# Count of selected rear port & position pairs much match the assigned number of positions
|
# Count of selected rear port & position pairs much match the assigned number of positions
|
||||||
if len(self.cleaned_data['rear_ports']) != self.cleaned_data['positions']:
|
if len(self.cleaned_data['rear_ports']) != self.cleaned_data['positions']:
|
||||||
@@ -1652,7 +1653,7 @@ class FrontPortForm(ModularDeviceComponentForm):
|
|||||||
"""
|
"""
|
||||||
occupied_rear_port_positions = [
|
occupied_rear_port_positions = [
|
||||||
f'{assignment.rear_port_id}:{assignment.rear_port_position}'
|
f'{assignment.rear_port_id}:{assignment.rear_port_position}'
|
||||||
for assignment in PortAssignment.objects.filter(front_port__device=device).exclude(front_port=front_port)
|
for assignment in PortAssignment.objects.filter(front_port__device=device).exclude(front_port=front_port.pk)
|
||||||
]
|
]
|
||||||
|
|
||||||
choices = []
|
choices = []
|
||||||
|
|||||||
@@ -269,58 +269,30 @@ class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm):
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
rear_port = forms.MultipleChoiceField(
|
|
||||||
choices=[],
|
|
||||||
label=_('Rear ports'),
|
|
||||||
help_text=_('Select one rear port assignment for each front port being created.'),
|
|
||||||
widget=forms.SelectMultiple(attrs={'size': 6})
|
|
||||||
)
|
|
||||||
|
|
||||||
# Override fieldsets from FrontPortForm to omit rear_port_position
|
# Override fieldsets from FrontPortForm to omit rear_port_position
|
||||||
fieldsets = (
|
fieldsets = (
|
||||||
FieldSet(
|
FieldSet(
|
||||||
'device', 'module', 'name', 'label', 'type', 'color', 'rear_port', 'mark_connected', 'description', 'tags',
|
'device', 'module', 'name', 'label', 'type', 'color', 'positions', 'rear_ports', 'mark_connected',
|
||||||
|
'description', 'tags',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
class Meta(model_forms.FrontPortForm.Meta):
|
class Meta:
|
||||||
exclude = ('name', 'label', 'positions')
|
model = FrontPort
|
||||||
|
fields = [
|
||||||
def __init__(self, *args, **kwargs):
|
'device', 'module', 'type', 'color', 'positions', 'mark_connected', 'description', 'owner', 'tags',
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
if device_id := self.data.get('device') or self.initial.get('device'):
|
|
||||||
device = Device.objects.get(pk=device_id)
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
# 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'].choices = choices
|
|
||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super(NetBoxModelForm, self).clean()
|
||||||
|
|
||||||
# Check that the number of FrontPorts to be created matches the selected number of RearPort positions
|
# Check that the number of FrontPorts to be created matches the selected number of RearPort positions
|
||||||
frontport_count = len(self.cleaned_data['name'])
|
frontport_count = len(self.cleaned_data['name'])
|
||||||
rearport_count = len(self.cleaned_data['rear_port'])
|
rearport_count = len(self.cleaned_data['rear_ports'])
|
||||||
if frontport_count != rearport_count:
|
if frontport_count != rearport_count:
|
||||||
raise forms.ValidationError({
|
raise forms.ValidationError({
|
||||||
'rear_port': _(
|
'rear_ports': _(
|
||||||
"The number of front ports to be created ({frontport_count}) must match the selected number of "
|
"The number of front ports to be created ({frontport_count}) must match the selected number of "
|
||||||
"rear port positions ({rearport_count})."
|
"rear port positions ({rearport_count})."
|
||||||
).format(
|
).format(
|
||||||
@@ -330,13 +302,10 @@ class FrontPortCreateForm(ComponentCreateForm, model_forms.FrontPortForm):
|
|||||||
})
|
})
|
||||||
|
|
||||||
def get_iterative_data(self, iteration):
|
def get_iterative_data(self, iteration):
|
||||||
|
positions = self.cleaned_data['positions']
|
||||||
# Assign rear port and position from selected set
|
offset = positions * iteration
|
||||||
rear_port, position = self.cleaned_data['rear_port'][iteration].split(':')
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'rear_port': int(rear_port),
|
'rear_ports': self.cleaned_data['rear_ports'][offset:offset + positions]
|
||||||
'rear_port_position': int(position),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import logging
|
import logging
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from copy import deepcopy
|
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.db import router, transaction
|
from django.db import router, transaction
|
||||||
@@ -563,7 +562,7 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
|
|||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
new_components = []
|
new_components = []
|
||||||
data = deepcopy(request.POST)
|
data = request.POST.copy()
|
||||||
pattern_count = len(form.cleaned_data[self.form.replication_fields[0]])
|
pattern_count = len(form.cleaned_data[self.form.replication_fields[0]])
|
||||||
|
|
||||||
for i in range(pattern_count):
|
for i in range(pattern_count):
|
||||||
@@ -572,7 +571,8 @@ class ComponentCreateView(GetReturnURLMixin, BaseObjectView):
|
|||||||
data[field_name] = form.cleaned_data[field_name][i]
|
data[field_name] = form.cleaned_data[field_name][i]
|
||||||
|
|
||||||
if hasattr(form, 'get_iterative_data'):
|
if hasattr(form, 'get_iterative_data'):
|
||||||
data.update(form.get_iterative_data(i))
|
for k, v in form.get_iterative_data(i).items():
|
||||||
|
data.setlist(k, v)
|
||||||
|
|
||||||
component_form = self.model_form(data)
|
component_form = self.model_form(data)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user