Fixes #75: Ignore a Device's occupied rack units when relocating it within a rack

This commit is contained in:
Jeremy Stretch 2016-06-28 14:10:16 -04:00
parent 03fa000d8d
commit fdfc32899d
2 changed files with 10 additions and 4 deletions

View File

@ -386,10 +386,13 @@ class DeviceForm(forms.ModelForm, BootstrapMixin):
# Rack position
try:
pk = self.instance.pk if self.instance.pk else None
if self.is_bound and self.data.get('rack') and str(self.data.get('face')):
position_choices = Rack.objects.get(pk=self.data['rack']).get_rack_units(face=self.data.get('face'))
position_choices = Rack.objects.get(pk=self.data['rack'])\
.get_rack_units(face=self.data.get('face'), exclude=pk)
elif self.initial.get('rack') and str(self.initial.get('face')):
position_choices = Rack.objects.get(pk=self.initial['rack']).get_rack_units(face=self.initial.get('face'))
position_choices = Rack.objects.get(pk=self.initial['rack'])\
.get_rack_units(face=self.initial.get('face'), exclude=pk)
else:
position_choices = []
except Rack.DoesNotExist:

View File

@ -215,12 +215,13 @@ class Rack(CreatedUpdatedModel):
return "{} ({})".format(self.name, self.facility_id)
return self.name
def get_rack_units(self, face=RACK_FACE_FRONT, remove_redundant=False):
def get_rack_units(self, face=RACK_FACE_FRONT, exclude=None, remove_redundant=False):
"""
Return a list of rack units as dictionaries. Example: {'device': None, 'face': 0, 'id': 48, 'name': 'U48'}
Each key 'device' is either a Device or None. By default, multi-U devices are repeated for each U they occupy.
:param face: Rack face (front or rear)
:param exclude: PK of a Device to exclude (optional); helpful when relocating a Device within a Rack
:param remove_redundant: If True, rack units occupied by a device already listed will be omitted
"""
@ -231,7 +232,9 @@ class Rack(CreatedUpdatedModel):
# Add devices to rack units list
if self.pk:
for device in Device.objects.select_related('device_type__manufacturer', 'device_role')\
.filter(rack=self, position__gt=0).filter(Q(face=face) | Q(device_type__is_full_depth=True)):
.exclude(pk=exclude)\
.filter(rack=self, position__gt=0)\
.filter(Q(face=face) | Q(device_type__is_full_depth=True)):
if remove_redundant:
elevation[device.position]['device'] = device
for u in range(device.position + 1, device.position + device.device_type.u_height):