From fdfc32899d12607821456d7e973d1327fef522b1 Mon Sep 17 00:00:00 2001 From: Jeremy Stretch Date: Tue, 28 Jun 2016 14:10:16 -0400 Subject: [PATCH] Fixes #75: Ignore a Device's occupied rack units when relocating it within a rack --- netbox/dcim/forms.py | 7 +++++-- netbox/dcim/models.py | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/netbox/dcim/forms.py b/netbox/dcim/forms.py index 776306a07..b158a8349 100644 --- a/netbox/dcim/forms.py +++ b/netbox/dcim/forms.py @@ -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: diff --git a/netbox/dcim/models.py b/netbox/dcim/models.py index c00a1043b..1e5ca1aed 100644 --- a/netbox/dcim/models.py +++ b/netbox/dcim/models.py @@ -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):