Browse Source

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

Jeremy Stretch 9 years ago
parent
commit
fdfc32899d
2 changed files with 10 additions and 4 deletions
  1. 5 2
      netbox/dcim/forms.py
  2. 5 2
      netbox/dcim/models.py

+ 5 - 2
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:

+ 5 - 2
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):