mirror of
https://github.com/netbox-community/netbox.git
synced 2025-12-19 03:42:25 -06:00
fixes #3428 - caching invalidation issues
Mitgate invalidation issues by using prefetch_related instead of select_related. Also use invalidated_update instead of just update.
This commit is contained in:
@@ -109,10 +109,8 @@ class RegionViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class SiteViewSet(CustomFieldModelViewSet):
|
||||
queryset = Site.objects.select_related(
|
||||
'region', 'tenant'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
queryset = Site.objects.prefetch_related(
|
||||
'region', 'tenant', 'tags'
|
||||
).annotate(
|
||||
device_count=get_subquery(Device, 'site'),
|
||||
rack_count=get_subquery(Rack, 'site'),
|
||||
@@ -140,7 +138,7 @@ class SiteViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class RackGroupViewSet(ModelViewSet):
|
||||
queryset = RackGroup.objects.select_related('site').annotate(
|
||||
queryset = RackGroup.objects.prefetch_related('site').annotate(
|
||||
rack_count=Count('racks')
|
||||
)
|
||||
serializer_class = serializers.RackGroupSerializer
|
||||
@@ -164,10 +162,8 @@ class RackRoleViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class RackViewSet(CustomFieldModelViewSet):
|
||||
queryset = Rack.objects.select_related(
|
||||
'site', 'group__site', 'role', 'tenant'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
queryset = Rack.objects.prefetch_related(
|
||||
'site', 'group__site', 'role', 'tenant', 'tags'
|
||||
).annotate(
|
||||
device_count=get_subquery(Device, 'rack'),
|
||||
powerfeed_count=get_subquery(PowerFeed, 'rack')
|
||||
@@ -206,7 +202,7 @@ class RackViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class RackReservationViewSet(ModelViewSet):
|
||||
queryset = RackReservation.objects.select_related('rack', 'user', 'tenant')
|
||||
queryset = RackReservation.objects.prefetch_related('rack', 'user', 'tenant')
|
||||
serializer_class = serializers.RackReservationSerializer
|
||||
filterset_class = filters.RackReservationFilter
|
||||
|
||||
@@ -234,7 +230,7 @@ class ManufacturerViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class DeviceTypeViewSet(CustomFieldModelViewSet):
|
||||
queryset = DeviceType.objects.select_related('manufacturer').prefetch_related('tags').annotate(
|
||||
queryset = DeviceType.objects.prefetch_related('manufacturer').prefetch_related('tags').annotate(
|
||||
device_count=Count('instances')
|
||||
)
|
||||
serializer_class = serializers.DeviceTypeSerializer
|
||||
@@ -246,49 +242,49 @@ class DeviceTypeViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class ConsolePortTemplateViewSet(ModelViewSet):
|
||||
queryset = ConsolePortTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = ConsolePortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.ConsolePortTemplateSerializer
|
||||
filterset_class = filters.ConsolePortTemplateFilter
|
||||
|
||||
|
||||
class ConsoleServerPortTemplateViewSet(ModelViewSet):
|
||||
queryset = ConsoleServerPortTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = ConsoleServerPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.ConsoleServerPortTemplateSerializer
|
||||
filterset_class = filters.ConsoleServerPortTemplateFilter
|
||||
|
||||
|
||||
class PowerPortTemplateViewSet(ModelViewSet):
|
||||
queryset = PowerPortTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = PowerPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.PowerPortTemplateSerializer
|
||||
filterset_class = filters.PowerPortTemplateFilter
|
||||
|
||||
|
||||
class PowerOutletTemplateViewSet(ModelViewSet):
|
||||
queryset = PowerOutletTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = PowerOutletTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.PowerOutletTemplateSerializer
|
||||
filterset_class = filters.PowerOutletTemplateFilter
|
||||
|
||||
|
||||
class InterfaceTemplateViewSet(ModelViewSet):
|
||||
queryset = InterfaceTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = InterfaceTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.InterfaceTemplateSerializer
|
||||
filterset_class = filters.InterfaceTemplateFilter
|
||||
|
||||
|
||||
class FrontPortTemplateViewSet(ModelViewSet):
|
||||
queryset = FrontPortTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = FrontPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.FrontPortTemplateSerializer
|
||||
filterset_class = filters.FrontPortTemplateFilter
|
||||
|
||||
|
||||
class RearPortTemplateViewSet(ModelViewSet):
|
||||
queryset = RearPortTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = RearPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.RearPortTemplateSerializer
|
||||
filterset_class = filters.RearPortTemplateFilter
|
||||
|
||||
|
||||
class DeviceBayTemplateViewSet(ModelViewSet):
|
||||
queryset = DeviceBayTemplate.objects.select_related('device_type__manufacturer')
|
||||
queryset = DeviceBayTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||
serializer_class = serializers.DeviceBayTemplateSerializer
|
||||
filterset_class = filters.DeviceBayTemplateFilter
|
||||
|
||||
@@ -324,11 +320,9 @@ class PlatformViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class DeviceViewSet(CustomFieldModelViewSet):
|
||||
queryset = Device.objects.select_related(
|
||||
queryset = Device.objects.prefetch_related(
|
||||
'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay',
|
||||
'virtual_chassis__master',
|
||||
).prefetch_related(
|
||||
'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
||||
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
||||
)
|
||||
filterset_class = filters.DeviceFilter
|
||||
|
||||
@@ -429,52 +423,36 @@ class DeviceViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class ConsolePortViewSet(CableTraceMixin, ModelViewSet):
|
||||
queryset = ConsolePort.objects.select_related(
|
||||
'device', 'connected_endpoint__device', 'cable'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = ConsolePort.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
|
||||
serializer_class = serializers.ConsolePortSerializer
|
||||
filterset_class = filters.ConsolePortFilter
|
||||
|
||||
|
||||
class ConsoleServerPortViewSet(CableTraceMixin, ModelViewSet):
|
||||
queryset = ConsoleServerPort.objects.select_related(
|
||||
'device', 'connected_endpoint__device', 'cable'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = ConsoleServerPort.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
|
||||
serializer_class = serializers.ConsoleServerPortSerializer
|
||||
filterset_class = filters.ConsoleServerPortFilter
|
||||
|
||||
|
||||
class PowerPortViewSet(CableTraceMixin, ModelViewSet):
|
||||
queryset = PowerPort.objects.select_related(
|
||||
'device', '_connected_poweroutlet__device', '_connected_powerfeed', 'cable'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
queryset = PowerPort.objects.prefetch_related(
|
||||
'device', '_connected_poweroutlet__device', '_connected_powerfeed', 'cable', 'tags'
|
||||
)
|
||||
serializer_class = serializers.PowerPortSerializer
|
||||
filterset_class = filters.PowerPortFilter
|
||||
|
||||
|
||||
class PowerOutletViewSet(CableTraceMixin, ModelViewSet):
|
||||
queryset = PowerOutlet.objects.select_related(
|
||||
'device', 'connected_endpoint__device', 'cable'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = PowerOutlet.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
|
||||
serializer_class = serializers.PowerOutletSerializer
|
||||
filterset_class = filters.PowerOutletFilter
|
||||
|
||||
|
||||
class InterfaceViewSet(CableTraceMixin, ModelViewSet):
|
||||
queryset = Interface.objects.filter(
|
||||
queryset = Interface.objects.prefetch_related(
|
||||
'device', '_connected_interface', '_connected_circuittermination', 'cable', 'ip_addresses', 'tags'
|
||||
).filter(
|
||||
device__isnull=False
|
||||
).select_related(
|
||||
'device', '_connected_interface', '_connected_circuittermination', 'cable'
|
||||
).prefetch_related(
|
||||
'ip_addresses', 'tags'
|
||||
)
|
||||
serializer_class = serializers.InterfaceSerializer
|
||||
filterset_class = filters.InterfaceFilter
|
||||
@@ -491,33 +469,25 @@ class InterfaceViewSet(CableTraceMixin, ModelViewSet):
|
||||
|
||||
|
||||
class FrontPortViewSet(ModelViewSet):
|
||||
queryset = FrontPort.objects.select_related(
|
||||
'device__device_type__manufacturer', 'rear_port', 'cable'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = FrontPort.objects.prefetch_related('device__device_type__manufacturer', 'rear_port', 'cable', 'tags')
|
||||
serializer_class = serializers.FrontPortSerializer
|
||||
filterset_class = filters.FrontPortFilter
|
||||
|
||||
|
||||
class RearPortViewSet(ModelViewSet):
|
||||
queryset = RearPort.objects.select_related(
|
||||
'device__device_type__manufacturer', 'cable'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = RearPort.objects.prefetch_related('device__device_type__manufacturer', 'cable', 'tags')
|
||||
serializer_class = serializers.RearPortSerializer
|
||||
filterset_class = filters.RearPortFilter
|
||||
|
||||
|
||||
class DeviceBayViewSet(ModelViewSet):
|
||||
queryset = DeviceBay.objects.select_related('installed_device').prefetch_related('tags')
|
||||
queryset = DeviceBay.objects.prefetch_related('installed_device').prefetch_related('tags')
|
||||
serializer_class = serializers.DeviceBaySerializer
|
||||
filterset_class = filters.DeviceBayFilter
|
||||
|
||||
|
||||
class InventoryItemViewSet(ModelViewSet):
|
||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer').prefetch_related('tags')
|
||||
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer').prefetch_related('tags')
|
||||
serializer_class = serializers.InventoryItemSerializer
|
||||
filterset_class = filters.InventoryItemFilter
|
||||
|
||||
@@ -527,7 +497,7 @@ class InventoryItemViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||
queryset = ConsolePort.objects.select_related(
|
||||
queryset = ConsolePort.objects.prefetch_related(
|
||||
'device', 'connected_endpoint__device'
|
||||
).filter(
|
||||
connected_endpoint__isnull=False
|
||||
@@ -537,7 +507,7 @@ class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||
|
||||
|
||||
class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||
queryset = PowerPort.objects.select_related(
|
||||
queryset = PowerPort.objects.prefetch_related(
|
||||
'device', 'connected_endpoint__device'
|
||||
).filter(
|
||||
_connected_poweroutlet__isnull=False
|
||||
@@ -547,7 +517,7 @@ class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||
|
||||
|
||||
class InterfaceConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||
queryset = Interface.objects.select_related(
|
||||
queryset = Interface.objects.prefetch_related(
|
||||
'device', '_connected_interface__device'
|
||||
).filter(
|
||||
# Avoid duplicate connections by only selecting the lower PK in a connected pair
|
||||
@@ -587,7 +557,7 @@ class VirtualChassisViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class PowerPanelViewSet(ModelViewSet):
|
||||
queryset = PowerPanel.objects.select_related(
|
||||
queryset = PowerPanel.objects.prefetch_related(
|
||||
'site', 'rack_group'
|
||||
).annotate(
|
||||
powerfeed_count=Count('powerfeeds')
|
||||
@@ -601,11 +571,7 @@ class PowerPanelViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class PowerFeedViewSet(CustomFieldModelViewSet):
|
||||
queryset = PowerFeed.objects.select_related(
|
||||
'power_panel', 'rack'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack', 'tags')
|
||||
serializer_class = serializers.PowerFeedSerializer
|
||||
filterset_class = filters.PowerFeedFilter
|
||||
|
||||
|
||||
@@ -632,7 +632,7 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
|
||||
)
|
||||
group_id = ChainedModelChoiceField(
|
||||
label='Rack group',
|
||||
queryset=RackGroup.objects.select_related('site'),
|
||||
queryset=RackGroup.objects.prefetch_related('site'),
|
||||
chains=(
|
||||
('site', 'site'),
|
||||
),
|
||||
@@ -745,7 +745,7 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm):
|
||||
)
|
||||
)
|
||||
group_id = FilterChoiceField(
|
||||
queryset=RackGroup.objects.select_related('site'),
|
||||
queryset=RackGroup.objects.prefetch_related('site'),
|
||||
label='Rack group',
|
||||
null_label='-- None --',
|
||||
widget=APISelectMultiple(
|
||||
@@ -1391,14 +1391,14 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
interface_ids = self.instance.vc_interfaces.values('pk')
|
||||
|
||||
# Collect interface IPs
|
||||
interface_ips = IPAddress.objects.select_related('interface').filter(
|
||||
interface_ips = IPAddress.objects.prefetch_related('interface').filter(
|
||||
family=family, interface_id__in=interface_ids
|
||||
)
|
||||
if interface_ips:
|
||||
ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips]
|
||||
ip_choices.append(('Interface IPs', ip_list))
|
||||
# Collect NAT IPs
|
||||
nat_ips = IPAddress.objects.select_related('nat_inside').filter(
|
||||
nat_ips = IPAddress.objects.prefetch_related('nat_inside').filter(
|
||||
family=family, nat_inside__interface__in=interface_ids
|
||||
)
|
||||
if nat_ips:
|
||||
@@ -1710,7 +1710,7 @@ class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
|
||||
)
|
||||
)
|
||||
rack_group_id = FilterChoiceField(
|
||||
queryset=RackGroup.objects.select_related(
|
||||
queryset=RackGroup.objects.prefetch_related(
|
||||
'site'
|
||||
),
|
||||
label='Rack group',
|
||||
@@ -1749,7 +1749,7 @@ class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
|
||||
)
|
||||
)
|
||||
device_type_id = FilterChoiceField(
|
||||
queryset=DeviceType.objects.select_related(
|
||||
queryset=DeviceType.objects.prefetch_related(
|
||||
'manufacturer'
|
||||
),
|
||||
label='Model',
|
||||
|
||||
@@ -607,7 +607,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
||||
|
||||
# Update racked devices if the assigned Site has been changed.
|
||||
if _site_id is not None and self.site_id != _site_id:
|
||||
Device.objects.filter(rack=self).update(site_id=self.site.pk)
|
||||
Device.objects.filter(rack=self).invalidated_update(site_id=self.site.pk)
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
@@ -664,7 +664,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
||||
|
||||
# Add devices to rack units list
|
||||
if self.pk:
|
||||
for device in Device.objects.select_related('device_type__manufacturer', 'device_role')\
|
||||
for device in Device.objects.prefetch_related('device_type__manufacturer', 'device_role')\
|
||||
.annotate(devicebay_count=Count('device_bays'))\
|
||||
.exclude(pk=exclude)\
|
||||
.filter(rack=self, position__gt=0)\
|
||||
@@ -697,7 +697,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
||||
"""
|
||||
|
||||
# Gather all devices which consume U space within the rack
|
||||
devices = self.devices.select_related('device_type').filter(position__gte=1).exclude(pk__in=exclude)
|
||||
devices = self.devices.prefetch_related('device_type').filter(position__gte=1).exclude(pk__in=exclude)
|
||||
|
||||
# Initialize the rack unit skeleton
|
||||
units = list(range(1, self.u_height + 1))
|
||||
@@ -1738,7 +1738,7 @@ class Device(ChangeLoggedModel, ConfigContextModel, CustomFieldModel):
|
||||
)
|
||||
|
||||
# Update Site and Rack assignment for any child Devices
|
||||
Device.objects.filter(parent_bay__device=self).update(site=self.site, rack=self.rack)
|
||||
Device.objects.filter(parent_bay__device=self).invalidated_update(site=self.site, rack=self.rack)
|
||||
|
||||
def to_csv(self):
|
||||
return (
|
||||
|
||||
@@ -10,7 +10,7 @@ def assign_virtualchassis_master(instance, created, **kwargs):
|
||||
When a VirtualChassis is created, automatically assign its master device to the VC.
|
||||
"""
|
||||
if created:
|
||||
Device.objects.filter(pk=instance.master.pk).update(virtual_chassis=instance, vc_position=None)
|
||||
Device.objects.filter(pk=instance.master.pk).invalidated_update(virtual_chassis=instance, vc_position=None)
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=VirtualChassis)
|
||||
@@ -18,7 +18,7 @@ def clear_virtualchassis_members(instance, **kwargs):
|
||||
"""
|
||||
When a VirtualChassis is deleted, nullify the vc_position and vc_priority fields of its prior members.
|
||||
"""
|
||||
Device.objects.filter(virtual_chassis=instance.pk).update(vc_position=None, vc_priority=None)
|
||||
Device.objects.filter(virtual_chassis=instance.pk).invalidated_update(vc_position=None, vc_priority=None)
|
||||
|
||||
|
||||
@receiver(post_save, sender=Cable)
|
||||
|
||||
@@ -3430,11 +3430,11 @@ class VirtualChassisTest(APITestCase):
|
||||
|
||||
# Create two VirtualChassis with three members each
|
||||
self.vc1 = VirtualChassis.objects.create(master=self.device1, domain='test-domain-1')
|
||||
Device.objects.filter(pk=self.device2.pk).update(virtual_chassis=self.vc1, vc_position=2)
|
||||
Device.objects.filter(pk=self.device3.pk).update(virtual_chassis=self.vc1, vc_position=3)
|
||||
Device.objects.filter(pk=self.device2.pk).invalidated_update(virtual_chassis=self.vc1, vc_position=2)
|
||||
Device.objects.filter(pk=self.device3.pk).invalidated_update(virtual_chassis=self.vc1, vc_position=3)
|
||||
self.vc2 = VirtualChassis.objects.create(master=self.device4, domain='test-domain-2')
|
||||
Device.objects.filter(pk=self.device5.pk).update(virtual_chassis=self.vc2, vc_position=2)
|
||||
Device.objects.filter(pk=self.device6.pk).update(virtual_chassis=self.vc2, vc_position=3)
|
||||
Device.objects.filter(pk=self.device5.pk).invalidated_update(virtual_chassis=self.vc2, vc_position=2)
|
||||
Device.objects.filter(pk=self.device6.pk).invalidated_update(virtual_chassis=self.vc2, vc_position=3)
|
||||
|
||||
def test_get_virtualchassis(self):
|
||||
|
||||
|
||||
@@ -442,11 +442,11 @@ class VirtualChassisTestCase(TestCase):
|
||||
|
||||
# Create three VirtualChassis with two members each
|
||||
vc1 = VirtualChassis.objects.create(master=device1, domain='test-domain-1')
|
||||
Device.objects.filter(pk=device2.pk).update(virtual_chassis=vc1, vc_position=2)
|
||||
Device.objects.filter(pk=device2.pk).invalidated_update(virtual_chassis=vc1, vc_position=2)
|
||||
vc2 = VirtualChassis.objects.create(master=device3, domain='test-domain-2')
|
||||
Device.objects.filter(pk=device4.pk).update(virtual_chassis=vc2, vc_position=2)
|
||||
Device.objects.filter(pk=device4.pk).invalidated_update(virtual_chassis=vc2, vc_position=2)
|
||||
vc3 = VirtualChassis.objects.create(master=device5, domain='test-domain-3')
|
||||
Device.objects.filter(pk=device6.pk).update(virtual_chassis=vc3, vc_position=2)
|
||||
Device.objects.filter(pk=device6.pk).invalidated_update(virtual_chassis=vc3, vc_position=2)
|
||||
|
||||
def test_virtualchassis_list(self):
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class SiteListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_site'
|
||||
queryset = Site.objects.select_related('region', 'tenant')
|
||||
queryset = Site.objects.prefetch_related('region', 'tenant')
|
||||
filter = filters.SiteFilter
|
||||
filter_form = forms.SiteFilterForm
|
||||
table = tables.SiteTable
|
||||
@@ -197,7 +197,7 @@ class SiteView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, slug):
|
||||
|
||||
site = get_object_or_404(Site.objects.select_related('region', 'tenant__group'), slug=slug)
|
||||
site = get_object_or_404(Site.objects.prefetch_related('region', 'tenant__group'), slug=slug)
|
||||
stats = {
|
||||
'rack_count': Rack.objects.filter(site=site).count(),
|
||||
'device_count': Device.objects.filter(site=site).count(),
|
||||
@@ -246,7 +246,7 @@ class SiteBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class SiteBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_site'
|
||||
queryset = Site.objects.select_related('region', 'tenant')
|
||||
queryset = Site.objects.prefetch_related('region', 'tenant')
|
||||
filter = filters.SiteFilter
|
||||
table = tables.SiteTable
|
||||
form = forms.SiteBulkEditForm
|
||||
@@ -255,7 +255,7 @@ class SiteBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_site'
|
||||
queryset = Site.objects.select_related('region', 'tenant')
|
||||
queryset = Site.objects.prefetch_related('region', 'tenant')
|
||||
filter = filters.SiteFilter
|
||||
table = tables.SiteTable
|
||||
default_return_url = 'dcim:site_list'
|
||||
@@ -267,7 +267,7 @@ class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class RackGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_rackgroup'
|
||||
queryset = RackGroup.objects.select_related('site').annotate(rack_count=Count('racks'))
|
||||
queryset = RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks'))
|
||||
filter = filters.RackGroupFilter
|
||||
filter_form = forms.RackGroupFilterForm
|
||||
table = tables.RackGroupTable
|
||||
@@ -294,7 +294,7 @@ class RackGroupBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_rackgroup'
|
||||
queryset = RackGroup.objects.select_related('site').annotate(rack_count=Count('racks'))
|
||||
queryset = RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks'))
|
||||
filter = filters.RackGroupFilter
|
||||
table = tables.RackGroupTable
|
||||
default_return_url = 'dcim:rackgroup_list'
|
||||
@@ -342,10 +342,8 @@ class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class RackListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_rack'
|
||||
queryset = Rack.objects.select_related(
|
||||
'site', 'group', 'tenant', 'role'
|
||||
).prefetch_related(
|
||||
'devices__device_type'
|
||||
queryset = Rack.objects.prefetch_related(
|
||||
'site', 'group', 'tenant', 'role', 'devices__device_type'
|
||||
).annotate(
|
||||
device_count=Count('devices')
|
||||
)
|
||||
@@ -363,11 +361,7 @@ class RackElevationListView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request):
|
||||
|
||||
racks = Rack.objects.select_related(
|
||||
'site', 'group', 'tenant', 'role'
|
||||
).prefetch_related(
|
||||
'devices__device_type'
|
||||
)
|
||||
racks = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role', 'devices__device_type')
|
||||
racks = filters.RackFilter(request.GET, racks).qs
|
||||
total_count = racks.count()
|
||||
|
||||
@@ -402,15 +396,18 @@ class RackView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
rack = get_object_or_404(Rack.objects.select_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
||||
rack = get_object_or_404(Rack.objects.prefetch_related('site__region', 'tenant__group', 'group', 'role'), pk=pk)
|
||||
|
||||
nonracked_devices = Device.objects.filter(rack=rack, position__isnull=True, parent_bay__isnull=True) \
|
||||
.select_related('device_type__manufacturer')
|
||||
nonracked_devices = Device.objects.filter(
|
||||
rack=rack,
|
||||
position__isnull=True,
|
||||
parent_bay__isnull=True
|
||||
).prefetch_related('device_type__manufacturer')
|
||||
next_rack = Rack.objects.filter(site=rack.site, name__gt=rack.name).order_by('name').first()
|
||||
prev_rack = Rack.objects.filter(site=rack.site, name__lt=rack.name).order_by('-name').first()
|
||||
|
||||
reservations = RackReservation.objects.filter(rack=rack)
|
||||
power_feeds = PowerFeed.objects.filter(rack=rack).select_related('power_panel')
|
||||
power_feeds = PowerFeed.objects.filter(rack=rack).prefetch_related('power_panel')
|
||||
|
||||
return render(request, 'dcim/rack.html', {
|
||||
'rack': rack,
|
||||
@@ -451,7 +448,7 @@ class RackBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_rack'
|
||||
queryset = Rack.objects.select_related('site', 'group', 'tenant', 'role')
|
||||
queryset = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role')
|
||||
filter = filters.RackFilter
|
||||
table = tables.RackTable
|
||||
form = forms.RackBulkEditForm
|
||||
@@ -460,7 +457,7 @@ class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_rack'
|
||||
queryset = Rack.objects.select_related('site', 'group', 'tenant', 'role')
|
||||
queryset = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role')
|
||||
filter = filters.RackFilter
|
||||
table = tables.RackTable
|
||||
default_return_url = 'dcim:rack_list'
|
||||
@@ -472,7 +469,7 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class RackReservationListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_rackreservation'
|
||||
queryset = RackReservation.objects.select_related('rack__site')
|
||||
queryset = RackReservation.objects.prefetch_related('rack__site')
|
||||
filter = filters.RackReservationFilter
|
||||
filter_form = forms.RackReservationFilterForm
|
||||
table = tables.RackReservationTable
|
||||
@@ -508,7 +505,7 @@ class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||
|
||||
class RackReservationBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_rackreservation'
|
||||
queryset = RackReservation.objects.select_related('rack', 'user')
|
||||
queryset = RackReservation.objects.prefetch_related('rack', 'user')
|
||||
filter = filters.RackReservationFilter
|
||||
table = tables.RackReservationTable
|
||||
form = forms.RackReservationBulkEditForm
|
||||
@@ -517,7 +514,7 @@ class RackReservationBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class RackReservationBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_rackreservation'
|
||||
queryset = RackReservation.objects.select_related('rack', 'user')
|
||||
queryset = RackReservation.objects.prefetch_related('rack', 'user')
|
||||
filter = filters.RackReservationFilter
|
||||
table = tables.RackReservationTable
|
||||
default_return_url = 'dcim:rackreservation_list'
|
||||
@@ -569,7 +566,7 @@ class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class DeviceTypeListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_devicetype'
|
||||
queryset = DeviceType.objects.select_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||
queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||
filter = filters.DeviceTypeFilter
|
||||
filter_form = forms.DeviceTypeFilterForm
|
||||
table = tables.DeviceTypeTable
|
||||
@@ -666,7 +663,7 @@ class DeviceTypeBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_devicetype'
|
||||
queryset = DeviceType.objects.select_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||
queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||
filter = filters.DeviceTypeFilter
|
||||
table = tables.DeviceTypeTable
|
||||
form = forms.DeviceTypeBulkEditForm
|
||||
@@ -675,7 +672,7 @@ class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_devicetype'
|
||||
queryset = DeviceType.objects.select_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||
queryset = DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances'))
|
||||
filter = filters.DeviceTypeFilter
|
||||
table = tables.DeviceTypeTable
|
||||
default_return_url = 'dcim:devicetype_list'
|
||||
@@ -907,7 +904,7 @@ class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class DeviceListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_device'
|
||||
queryset = Device.objects.select_related(
|
||||
queryset = Device.objects.prefetch_related(
|
||||
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6'
|
||||
)
|
||||
filter = filters.DeviceFilter
|
||||
@@ -921,7 +918,7 @@ class DeviceView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device.objects.select_related(
|
||||
device = get_object_or_404(Device.objects.prefetch_related(
|
||||
'site__region', 'rack__group', 'tenant__group', 'device_role', 'platform'
|
||||
), pk=pk)
|
||||
|
||||
@@ -934,32 +931,31 @@ class DeviceView(PermissionRequiredMixin, View):
|
||||
vc_members = []
|
||||
|
||||
# Console ports
|
||||
console_ports = device.consoleports.select_related('connected_endpoint__device', 'cable')
|
||||
console_ports = device.consoleports.prefetch_related('connected_endpoint__device', 'cable')
|
||||
|
||||
# Console server ports
|
||||
consoleserverports = device.consoleserverports.select_related('connected_endpoint__device', 'cable')
|
||||
consoleserverports = device.consoleserverports.prefetch_related('connected_endpoint__device', 'cable')
|
||||
|
||||
# Power ports
|
||||
power_ports = device.powerports.select_related('_connected_poweroutlet__device', 'cable')
|
||||
power_ports = device.powerports.prefetch_related('_connected_poweroutlet__device', 'cable')
|
||||
|
||||
# Power outlets
|
||||
poweroutlets = device.poweroutlets.select_related('connected_endpoint__device', 'cable', 'power_port')
|
||||
poweroutlets = device.poweroutlets.prefetch_related('connected_endpoint__device', 'cable', 'power_port')
|
||||
|
||||
# Interfaces
|
||||
interfaces = device.vc_interfaces.select_related(
|
||||
'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable'
|
||||
).prefetch_related(
|
||||
interfaces = device.vc_interfaces.prefetch_related(
|
||||
'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable',
|
||||
'cable__termination_a', 'cable__termination_b', 'ip_addresses', 'tags'
|
||||
)
|
||||
|
||||
# Front ports
|
||||
front_ports = device.frontports.select_related('rear_port', 'cable')
|
||||
front_ports = device.frontports.prefetch_related('rear_port', 'cable')
|
||||
|
||||
# Rear ports
|
||||
rear_ports = device.rearports.select_related('cable')
|
||||
rear_ports = device.rearports.prefetch_related('cable')
|
||||
|
||||
# Device bays
|
||||
device_bays = device.device_bays.select_related('installed_device__device_type__manufacturer')
|
||||
device_bays = device.device_bays.prefetch_related('installed_device__device_type__manufacturer')
|
||||
|
||||
# Services
|
||||
services = device.services.all()
|
||||
@@ -972,7 +968,7 @@ class DeviceView(PermissionRequiredMixin, View):
|
||||
site=device.site, device_role=device.device_role
|
||||
).exclude(
|
||||
pk=device.pk
|
||||
).select_related(
|
||||
).prefetch_related(
|
||||
'rack', 'device_type__manufacturer'
|
||||
)[:10]
|
||||
|
||||
@@ -1005,10 +1001,8 @@ class DeviceInventoryView(PermissionRequiredMixin, View):
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
inventory_items = InventoryItem.objects.filter(
|
||||
device=device, parent=None
|
||||
).select_related(
|
||||
'manufacturer'
|
||||
).prefetch_related(
|
||||
'child_items'
|
||||
'manufacturer', 'child_items'
|
||||
)
|
||||
|
||||
return render(request, 'dcim/device_inventory.html', {
|
||||
@@ -1037,7 +1031,7 @@ class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
||||
def get(self, request, pk):
|
||||
|
||||
device = get_object_or_404(Device, pk=pk)
|
||||
interfaces = device.vc_interfaces.connectable().select_related(
|
||||
interfaces = device.vc_interfaces.connectable().prefetch_related(
|
||||
'_connected_interface__device'
|
||||
)
|
||||
|
||||
@@ -1114,7 +1108,7 @@ class ChildDeviceBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_device'
|
||||
queryset = Device.objects.select_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
|
||||
queryset = Device.objects.prefetch_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
|
||||
filter = filters.DeviceFilter
|
||||
table = tables.DeviceTable
|
||||
form = forms.DeviceBulkEditForm
|
||||
@@ -1123,7 +1117,7 @@ class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_device'
|
||||
queryset = Device.objects.select_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
|
||||
queryset = Device.objects.prefetch_related('tenant', 'site', 'rack', 'device_role', 'device_type__manufacturer')
|
||||
filter = filters.DeviceFilter
|
||||
table = tables.DeviceTable
|
||||
default_return_url = 'dcim:device_list'
|
||||
@@ -1310,7 +1304,7 @@ class InterfaceView(PermissionRequiredMixin, View):
|
||||
|
||||
# Get assigned IP addresses
|
||||
ipaddress_table = InterfaceIPAddressTable(
|
||||
data=interface.ip_addresses.select_related('vrf', 'tenant'),
|
||||
data=interface.ip_addresses.prefetch_related('vrf', 'tenant'),
|
||||
orderable=False
|
||||
)
|
||||
|
||||
@@ -1319,7 +1313,7 @@ class InterfaceView(PermissionRequiredMixin, View):
|
||||
if interface.untagged_vlan is not None:
|
||||
vlans.append(interface.untagged_vlan)
|
||||
vlans[0].tagged = False
|
||||
for vlan in interface.tagged_vlans.select_related('site', 'group', 'tenant', 'role'):
|
||||
for vlan in interface.tagged_vlans.prefetch_related('site', 'group', 'tenant', 'role'):
|
||||
vlan.tagged = True
|
||||
vlans.append(vlan)
|
||||
vlan_table = InterfaceVLANTable(
|
||||
@@ -1842,7 +1836,7 @@ class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport')
|
||||
queryset = ConsolePort.objects.select_related(
|
||||
queryset = ConsolePort.objects.prefetch_related(
|
||||
'device', 'connected_endpoint__device'
|
||||
).filter(
|
||||
connected_endpoint__isnull=False
|
||||
@@ -1873,7 +1867,7 @@ class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet')
|
||||
queryset = PowerPort.objects.select_related(
|
||||
queryset = PowerPort.objects.prefetch_related(
|
||||
'device', '_connected_poweroutlet__device'
|
||||
).filter(
|
||||
_connected_poweroutlet__isnull=False
|
||||
@@ -1904,7 +1898,7 @@ class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_interface'
|
||||
queryset = Interface.objects.select_related(
|
||||
queryset = Interface.objects.prefetch_related(
|
||||
'device', 'cable', '_connected_interface__device'
|
||||
).filter(
|
||||
# Avoid duplicate connections by only selecting the lower PK in a connected pair
|
||||
@@ -1947,7 +1941,7 @@ class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||
|
||||
class InventoryItemListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_inventoryitem'
|
||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
||||
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
|
||||
filter = filters.InventoryItemFilter
|
||||
filter_form = forms.InventoryItemFilterForm
|
||||
table = tables.InventoryItemTable
|
||||
@@ -1982,7 +1976,7 @@ class InventoryItemBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class InventoryItemBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_inventoryitem'
|
||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
||||
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
|
||||
filter = filters.InventoryItemFilter
|
||||
table = tables.InventoryItemTable
|
||||
form = forms.InventoryItemBulkEditForm
|
||||
@@ -1991,7 +1985,7 @@ class InventoryItemBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_inventoryitem'
|
||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
||||
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
|
||||
table = tables.InventoryItemTable
|
||||
template_name = 'dcim/inventoryitem_bulk_delete.html'
|
||||
default_return_url = 'dcim:inventoryitem_list'
|
||||
@@ -2003,7 +1997,7 @@ class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class VirtualChassisListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_virtualchassis'
|
||||
queryset = VirtualChassis.objects.select_related('master').annotate(member_count=Count('members'))
|
||||
queryset = VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members'))
|
||||
table = tables.VirtualChassisTable
|
||||
filter = filters.VirtualChassisFilter
|
||||
filter_form = forms.VirtualChassisFilterForm
|
||||
@@ -2023,7 +2017,7 @@ class VirtualChassisCreateView(PermissionRequiredMixin, View):
|
||||
return redirect('dcim:device_list')
|
||||
device_queryset = Device.objects.filter(
|
||||
pk__in=pk_form.cleaned_data.get('pk')
|
||||
).select_related('rack').order_by('vc_position')
|
||||
).prefetch_related('rack').order_by('vc_position')
|
||||
|
||||
VCMemberFormSet = modelformset_factory(
|
||||
model=Device,
|
||||
@@ -2077,7 +2071,7 @@ class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
formset=forms.BaseVCMemberFormSet,
|
||||
extra=0
|
||||
)
|
||||
members_queryset = virtual_chassis.members.select_related('rack').order_by('vc_position')
|
||||
members_queryset = virtual_chassis.members.prefetch_related('rack').order_by('vc_position')
|
||||
|
||||
vc_form = forms.VirtualChassisForm(instance=virtual_chassis)
|
||||
vc_form.fields['master'].queryset = members_queryset
|
||||
@@ -2098,7 +2092,7 @@ class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
formset=forms.BaseVCMemberFormSet,
|
||||
extra=0
|
||||
)
|
||||
members_queryset = virtual_chassis.members.select_related('rack').order_by('vc_position')
|
||||
members_queryset = virtual_chassis.members.prefetch_related('rack').order_by('vc_position')
|
||||
|
||||
vc_form = forms.VirtualChassisForm(request.POST, instance=virtual_chassis)
|
||||
vc_form.fields['master'].queryset = members_queryset
|
||||
@@ -2114,7 +2108,7 @@ class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
||||
# Nullify the vc_position of each member first to allow reordering without raising an IntegrityError on
|
||||
# duplicate positions. Then save each member instance.
|
||||
members = formset.save(commit=False)
|
||||
Device.objects.filter(pk__in=[m.pk for m in members]).update(vc_position=None)
|
||||
Device.objects.filter(pk__in=[m.pk for m in members]).invalidated_update(vc_position=None)
|
||||
for member in members:
|
||||
member.save()
|
||||
|
||||
@@ -2215,12 +2209,13 @@ class VirtualChassisRemoveMemberView(PermissionRequiredMixin, GetReturnURLMixin,
|
||||
|
||||
if form.is_valid():
|
||||
|
||||
Device.objects.filter(pk=device.pk).update(
|
||||
Device.objects.filter(pk=device.pk).invalidated_update(
|
||||
virtual_chassis=None,
|
||||
vc_position=None,
|
||||
vc_priority=None
|
||||
)
|
||||
|
||||
|
||||
msg = 'Removed {} from virtual chassis {}'.format(device, device.virtual_chassis)
|
||||
messages.success(request, msg)
|
||||
|
||||
@@ -2239,7 +2234,7 @@ class VirtualChassisRemoveMemberView(PermissionRequiredMixin, GetReturnURLMixin,
|
||||
|
||||
class PowerPanelListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_powerpanel'
|
||||
queryset = PowerPanel.objects.select_related(
|
||||
queryset = PowerPanel.objects.prefetch_related(
|
||||
'site', 'rack_group'
|
||||
).annotate(
|
||||
powerfeed_count=Count('powerfeeds')
|
||||
@@ -2255,9 +2250,9 @@ class PowerPanelView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
powerpanel = get_object_or_404(PowerPanel.objects.select_related('site', 'rack_group'), pk=pk)
|
||||
powerpanel = get_object_or_404(PowerPanel.objects.prefetch_related('site', 'rack_group'), pk=pk)
|
||||
powerfeed_table = tables.PowerFeedTable(
|
||||
data=PowerFeed.objects.filter(power_panel=powerpanel).select_related('rack'),
|
||||
data=PowerFeed.objects.filter(power_panel=powerpanel).prefetch_related('rack'),
|
||||
orderable=False
|
||||
)
|
||||
powerfeed_table.exclude = ['power_panel']
|
||||
@@ -2294,7 +2289,7 @@ class PowerPanelBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_powerpanel'
|
||||
queryset = PowerPanel.objects.select_related(
|
||||
queryset = PowerPanel.objects.prefetch_related(
|
||||
'site', 'rack_group'
|
||||
).annotate(
|
||||
rack_count=Count('powerfeeds')
|
||||
@@ -2310,7 +2305,7 @@ class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class PowerFeedListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'dcim.view_powerfeed'
|
||||
queryset = PowerFeed.objects.select_related(
|
||||
queryset = PowerFeed.objects.prefetch_related(
|
||||
'power_panel', 'rack'
|
||||
)
|
||||
filter = filters.PowerFeedFilter
|
||||
@@ -2324,7 +2319,7 @@ class PowerFeedView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
powerfeed = get_object_or_404(PowerFeed.objects.select_related('power_panel', 'rack'), pk=pk)
|
||||
powerfeed = get_object_or_404(PowerFeed.objects.prefetch_related('power_panel', 'rack'), pk=pk)
|
||||
|
||||
return render(request, 'dcim/powerfeed.html', {
|
||||
'powerfeed': powerfeed,
|
||||
@@ -2358,7 +2353,7 @@ class PowerFeedBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'dcim.change_powerfeed'
|
||||
queryset = PowerFeed.objects.select_related('power_panel', 'rack')
|
||||
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
|
||||
filter = filters.PowerFeedFilter
|
||||
table = tables.PowerFeedTable
|
||||
form = forms.PowerFeedBulkEditForm
|
||||
@@ -2367,7 +2362,7 @@ class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class PowerFeedBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'dcim.delete_powerfeed'
|
||||
queryset = PowerFeed.objects.select_related('power_panel', 'rack')
|
||||
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
|
||||
filter = filters.PowerFeedFilter
|
||||
table = tables.PowerFeedTable
|
||||
default_return_url = 'dcim:powerfeed_list'
|
||||
|
||||
Reference in New Issue
Block a user