Fix unrestricted evaluations of RestrictedQuerySet

This commit is contained in:
Jeremy Stretch
2020-06-29 13:30:41 -04:00
parent 9ea4f82eaa
commit a47a100cb7
3 changed files with 66 additions and 57 deletions

View File

@@ -580,7 +580,11 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
if self.pk:
# Validate that Rack is tall enough to house the installed Devices
top_device = Device.objects.filter(rack=self).exclude(position__isnull=True).order_by('-position').first()
top_device = Device.objects.unrestricted().filter(
rack=self
).exclude(
position__isnull=True
).order_by('-position').first()
if top_device:
min_height = top_device.position + top_device.device_type.u_height - 1
if self.u_height < min_height:
@@ -601,13 +605,13 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
# Record the original site assignment for this rack.
_site_id = None
if self.pk:
_site_id = Rack.objects.get(pk=self.pk).site_id
_site_id = Rack.objects.unrestricted().get(pk=self.pk).site_id
super().save(*args, **kwargs)
# Update racked devices if the assigned Site has been changed.
if _site_id is not None and self.site_id != _site_id:
devices = Device.objects.filter(rack=self)
devices = Device.objects.unrestricted().filter(rack=self)
for device in devices:
device.site = self.site
device.save()
@@ -1125,7 +1129,7 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
# room to expand within their racks. This validation will impose a very high performance penalty when there are
# many instances to check, but increasing the u_height of a DeviceType should be a very rare occurrence.
if self.pk and self.u_height > self._original_u_height:
for d in Device.objects.filter(device_type=self, position__isnull=False):
for d in Device.objects.unrestricted().filter(device_type=self, position__isnull=False):
face_required = None if self.is_full_depth else d.face
u_available = d.rack.get_available_units(
u_height=self.u_height,
@@ -1140,7 +1144,10 @@ class DeviceType(ChangeLoggedModel, CustomFieldModel):
# If modifying the height of an existing DeviceType to 0U, check for any instances assigned to a rack position.
elif self.pk and self._original_u_height > 0 and self.u_height == 0:
racked_instance_count = Device.objects.filter(device_type=self, position__isnull=False).count()
racked_instance_count = Device.objects.unrestricted().filter(
device_type=self,
position__isnull=False
).count()
if racked_instance_count:
url = f"{reverse('dcim:device_list')}?manufactuer_id={self.manufacturer_id}&device_type_id={self.pk}"
raise ValidationError({
@@ -1493,7 +1500,11 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
# because Django does not consider two NULL fields to be equal, and thus will not trigger a violation
# of the uniqueness constraint without manual intervention.
if self.name and self.tenant is None:
if Device.objects.exclude(pk=self.pk).filter(name=self.name, site=self.site, tenant__isnull=True):
if Device.objects.unrestricted().exclude(pk=self.pk).filter(
name=self.name,
site=self.site,
tenant__isnull=True
):
raise ValidationError({
'name': 'A device with this name already exists.'
})
@@ -1623,32 +1634,32 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
# If this is a new Device, instantiate all of the related components per the DeviceType definition
if is_new:
ConsolePort.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.consoleport_templates.all()]
[x.instantiate(self) for x in self.device_type.consoleport_templates.unrestricted()]
)
ConsoleServerPort.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.consoleserverport_templates.all()]
[x.instantiate(self) for x in self.device_type.consoleserverport_templates.unrestricted()]
)
PowerPort.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.powerport_templates.all()]
[x.instantiate(self) for x in self.device_type.powerport_templates.unrestricted()]
)
PowerOutlet.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.poweroutlet_templates.all()]
[x.instantiate(self) for x in self.device_type.poweroutlet_templates.unrestricted()]
)
Interface.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.interface_templates.all()]
[x.instantiate(self) for x in self.device_type.interface_templates.unrestricted()]
)
RearPort.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.rearport_templates.all()]
[x.instantiate(self) for x in self.device_type.rearport_templates.unrestricted()]
)
FrontPort.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.frontport_templates.all()]
[x.instantiate(self) for x in self.device_type.frontport_templates.unrestricted()]
)
DeviceBay.objects.bulk_create(
[x.instantiate(self) for x in self.device_type.device_bay_templates.all()]
[x.instantiate(self) for x in self.device_type.device_bay_templates.unrestricted()]
)
# Update Site and Rack assignment for any child Devices
devices = Device.objects.filter(parent_bay__device=self)
devices = Device.objects.unrestricted().filter(parent_bay__device=self)
for device in devices:
device.site = self.site
device.rack = self.rack
@@ -1739,7 +1750,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
"""
Return the set of child Devices installed in DeviceBays within this Device.
"""
return Device.objects.filter(parent_bay__device=self.pk)
return Device.objects.unrestricted().filter(parent_bay__device=self.pk)
def get_status_class(self):
return self.STATUS_CLASS_MAP.get(self.status)
@@ -1796,7 +1807,7 @@ class VirtualChassis(ChangeLoggedModel):
def delete(self, *args, **kwargs):
# Check for LAG interfaces split across member chassis
interfaces = Interface.objects.filter(
interfaces = Interface.objects.unrestricted().filter(
device__in=self.members.all(),
lag__isnull=False
).exclude(
@@ -2169,7 +2180,7 @@ class Cable(ChangeLoggedModel):
if not hasattr(self, 'termination_a_type'):
raise ValidationError('Termination A type has not been specified')
try:
self.termination_a_type.model_class().objects.get(pk=self.termination_a_id)
self.termination_a_type.model_class().objects.unrestricted().get(pk=self.termination_a_id)
except ObjectDoesNotExist:
raise ValidationError({
'termination_a': 'Invalid ID for type {}'.format(self.termination_a_type)
@@ -2179,7 +2190,7 @@ class Cable(ChangeLoggedModel):
if not hasattr(self, 'termination_b_type'):
raise ValidationError('Termination B type has not been specified')
try:
self.termination_b_type.model_class().objects.get(pk=self.termination_b_id)
self.termination_b_type.model_class().objects.unrestricted().get(pk=self.termination_b_id)
except ObjectDoesNotExist:
raise ValidationError({
'termination_b': 'Invalid ID for type {}'.format(self.termination_b_type)