mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 01:41:22 -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:
parent
dd4dafa7be
commit
ade844f7a7
@ -43,7 +43,7 @@ class DeviceConnectionsReport(Report):
|
||||
def test_console_connection(self):
|
||||
|
||||
# Check that every console port for every active device has a connection defined.
|
||||
for console_port in ConsolePort.objects.select_related('device').filter(device__status=DEVICE_STATUS_ACTIVE):
|
||||
for console_port in ConsolePort.objects.prefetch_related('device').filter(device__status=DEVICE_STATUS_ACTIVE):
|
||||
if console_port.connected_endpoint is None:
|
||||
self.log_failure(
|
||||
console_port.device,
|
||||
|
@ -38,7 +38,7 @@ Add the name of the new field to `csv_headers` and included a CSV-friendly repre
|
||||
|
||||
### 4. Update relevant querysets
|
||||
|
||||
If you're adding a relational field (e.g. `ForeignKey`) and intend to include the data when retreiving a list of objects, be sure to include the field using `select_related()` or `prefetch_related()` as appropriate. This will optimize the view and avoid excessive database lookups.
|
||||
If you're adding a relational field (e.g. `ForeignKey`) and intend to include the data when retreiving a list of objects, be sure to include the field using `prefetch_related()` as appropriate. This will optimize the view and avoid excessive database lookups.
|
||||
|
||||
### 5. Update API serializer
|
||||
|
||||
|
@ -62,7 +62,7 @@ class CircuitTypeViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class CircuitViewSet(CustomFieldModelViewSet):
|
||||
queryset = Circuit.objects.select_related('type', 'tenant', 'provider').prefetch_related('tags')
|
||||
queryset = Circuit.objects.prefetch_related('type', 'tenant', 'provider').prefetch_related('tags')
|
||||
serializer_class = serializers.CircuitSerializer
|
||||
filterset_class = filters.CircuitFilter
|
||||
|
||||
@ -72,7 +72,7 @@ class CircuitViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class CircuitTerminationViewSet(ModelViewSet):
|
||||
queryset = CircuitTermination.objects.select_related(
|
||||
queryset = CircuitTermination.objects.prefetch_related(
|
||||
'circuit', 'site', 'connected_endpoint__device', 'cable'
|
||||
)
|
||||
serializer_class = serializers.CircuitTerminationSerializer
|
||||
|
@ -295,6 +295,6 @@ class CircuitTermination(CableTermination):
|
||||
def get_peer_termination(self):
|
||||
peer_side = 'Z' if self.term_side == 'A' else 'A'
|
||||
try:
|
||||
return CircuitTermination.objects.select_related('site').get(circuit=self.circuit, term_side=peer_side)
|
||||
return CircuitTermination.objects.prefetch_related('site').get(circuit=self.circuit, term_side=peer_side)
|
||||
except CircuitTermination.DoesNotExist:
|
||||
return None
|
||||
|
@ -10,4 +10,4 @@ def update_circuit(instance, **kwargs):
|
||||
"""
|
||||
When a CircuitTermination has been modified, update the last_updated time of its parent Circuit.
|
||||
"""
|
||||
Circuit.objects.filter(pk=instance.circuit_id).update(last_updated=timezone.now())
|
||||
Circuit.objects.filter(pk=instance.circuit_id).invalidated_update(last_updated=timezone.now())
|
||||
|
@ -35,11 +35,7 @@ class ProviderView(PermissionRequiredMixin, View):
|
||||
def get(self, request, slug):
|
||||
|
||||
provider = get_object_or_404(Provider, slug=slug)
|
||||
circuits = Circuit.objects.filter(provider=provider).select_related(
|
||||
'type', 'tenant'
|
||||
).prefetch_related(
|
||||
'terminations__site'
|
||||
)
|
||||
circuits = Circuit.objects.filter(provider=provider).prefetch_related('type', 'tenant', 'terminations__site')
|
||||
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
|
||||
|
||||
return render(request, 'circuits/provider.html', {
|
||||
@ -134,10 +130,8 @@ class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
class CircuitListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'circuits.view_circuit'
|
||||
_terminations = CircuitTermination.objects.filter(circuit=OuterRef('pk'))
|
||||
queryset = Circuit.objects.select_related(
|
||||
'provider', 'type', 'tenant'
|
||||
).prefetch_related(
|
||||
'terminations__site'
|
||||
queryset = Circuit.objects.prefetch_related(
|
||||
'provider', 'type', 'tenant', 'terminations__site'
|
||||
).annotate(
|
||||
a_side=Subquery(_terminations.filter(term_side='A').values('site__name')[:1]),
|
||||
z_side=Subquery(_terminations.filter(term_side='Z').values('site__name')[:1]),
|
||||
@ -153,13 +147,13 @@ class CircuitView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
circuit = get_object_or_404(Circuit.objects.select_related('provider', 'type', 'tenant__group'), pk=pk)
|
||||
termination_a = CircuitTermination.objects.select_related(
|
||||
circuit = get_object_or_404(Circuit.objects.prefetch_related('provider', 'type', 'tenant__group'), pk=pk)
|
||||
termination_a = CircuitTermination.objects.prefetch_related(
|
||||
'site__region', 'connected_endpoint__device'
|
||||
).filter(
|
||||
circuit=circuit, term_side=TERM_SIDE_A
|
||||
).first()
|
||||
termination_z = CircuitTermination.objects.select_related(
|
||||
termination_z = CircuitTermination.objects.prefetch_related(
|
||||
'site__region', 'connected_endpoint__device'
|
||||
).filter(
|
||||
circuit=circuit, term_side=TERM_SIDE_Z
|
||||
@ -199,7 +193,7 @@ class CircuitBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'circuits.change_circuit'
|
||||
queryset = Circuit.objects.select_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
|
||||
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
|
||||
filter = filters.CircuitFilter
|
||||
table = tables.CircuitTable
|
||||
form = forms.CircuitBulkEditForm
|
||||
@ -208,7 +202,7 @@ class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'circuits.delete_circuit'
|
||||
queryset = Circuit.objects.select_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
|
||||
queryset = Circuit.objects.prefetch_related('provider', 'type', 'tenant').prefetch_related('terminations__site')
|
||||
filter = filters.CircuitFilter
|
||||
table = tables.CircuitTable
|
||||
default_return_url = 'circuits:circuit_list'
|
||||
|
@ -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'
|
||||
|
@ -120,7 +120,7 @@ class ExportTemplateViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class TopologyMapViewSet(ModelViewSet):
|
||||
queryset = TopologyMap.objects.select_related('site')
|
||||
queryset = TopologyMap.objects.prefetch_related('site')
|
||||
serializer_class = serializers.TopologyMapSerializer
|
||||
filterset_class = filters.TopologyMapFilter
|
||||
|
||||
@ -260,6 +260,6 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
|
||||
"""
|
||||
Retrieve a list of recent changes.
|
||||
"""
|
||||
queryset = ObjectChange.objects.select_related('user')
|
||||
queryset = ObjectChange.objects.prefetch_related('user')
|
||||
serializer_class = serializers.ObjectChangeSerializer
|
||||
filterset_class = filters.ObjectChangeFilter
|
||||
|
@ -111,8 +111,10 @@ class CustomFieldForm(forms.ModelForm):
|
||||
|
||||
# If editing an existing object, initialize values for all custom fields
|
||||
if self.instance.pk:
|
||||
existing_values = CustomFieldValue.objects.filter(obj_type=self.obj_type, obj_id=self.instance.pk)\
|
||||
.select_related('field')
|
||||
existing_values = CustomFieldValue.objects.filter(
|
||||
obj_type=self.obj_type,
|
||||
obj_id=self.instance.pk
|
||||
).prefetch_related('field')
|
||||
for cfv in existing_values:
|
||||
self.initial['cf_{}'.format(str(cfv.field.name))] = cfv.serialized_value
|
||||
|
||||
@ -120,9 +122,11 @@ class CustomFieldForm(forms.ModelForm):
|
||||
|
||||
for field_name in self.custom_fields:
|
||||
try:
|
||||
cfv = CustomFieldValue.objects.select_related('field').get(field=self.fields[field_name].model,
|
||||
obj_type=self.obj_type,
|
||||
obj_id=self.instance.pk)
|
||||
cfv = CustomFieldValue.objects.prefetch_related('field').get(
|
||||
field=self.fields[field_name].model,
|
||||
obj_type=self.obj_type,
|
||||
obj_id=self.instance.pk
|
||||
)
|
||||
except CustomFieldValue.DoesNotExist:
|
||||
# Skip this field if none exists already and its value is empty
|
||||
if self.cleaned_data[field_name] in [None, '']:
|
||||
|
@ -569,7 +569,7 @@ class TopologyMap(models.Model):
|
||||
# Add each device to the graph
|
||||
devices = []
|
||||
for query in device_set.strip(';').split(';'): # Split regexes on semicolons
|
||||
devices += Device.objects.filter(name__regex=query).select_related('device_role')
|
||||
devices += Device.objects.filter(name__regex=query).prefetch_related('device_role')
|
||||
# Remove duplicate devices
|
||||
devices = [d for d in devices if d.id not in seen]
|
||||
seen.update([d.id for d in devices])
|
||||
@ -607,7 +607,7 @@ class TopologyMap(models.Model):
|
||||
from dcim.models import Interface
|
||||
|
||||
# Add all interface connections to the graph
|
||||
connected_interfaces = Interface.objects.select_related(
|
||||
connected_interfaces = Interface.objects.prefetch_related(
|
||||
'_connected_interface__device'
|
||||
).filter(
|
||||
Q(device__in=devices) | Q(_connected_interface__device__in=devices),
|
||||
|
@ -47,10 +47,8 @@ class TagView(View):
|
||||
tag = get_object_or_404(Tag, slug=slug)
|
||||
tagged_items = TaggedItem.objects.filter(
|
||||
tag=tag
|
||||
).select_related(
|
||||
'content_type'
|
||||
).prefetch_related(
|
||||
'content_object'
|
||||
'content_type', 'content_object'
|
||||
)
|
||||
|
||||
# Generate a table of all items tagged with this Tag
|
||||
@ -178,7 +176,7 @@ class ObjectConfigContextView(View):
|
||||
|
||||
class ObjectChangeListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'extras.view_objectchange'
|
||||
queryset = ObjectChange.objects.select_related('user', 'changed_object_type')
|
||||
queryset = ObjectChange.objects.prefetch_related('user', 'changed_object_type')
|
||||
filter = filters.ObjectChangeFilter
|
||||
filter_form = ObjectChangeFilterForm
|
||||
table = ObjectChangeTable
|
||||
@ -217,7 +215,7 @@ class ObjectChangeLogView(View):
|
||||
|
||||
# Gather all changes for this object (and its related objects)
|
||||
content_type = ContentType.objects.get_for_model(model)
|
||||
objectchanges = ObjectChange.objects.select_related(
|
||||
objectchanges = ObjectChange.objects.prefetch_related(
|
||||
'user', 'changed_object_type'
|
||||
).filter(
|
||||
Q(changed_object_type=content_type, changed_object_id=obj.pk) |
|
||||
|
@ -33,7 +33,7 @@ class IPAMFieldChoicesViewSet(FieldChoicesViewSet):
|
||||
#
|
||||
|
||||
class VRFViewSet(CustomFieldModelViewSet):
|
||||
queryset = VRF.objects.select_related('tenant').prefetch_related('tags').annotate(
|
||||
queryset = VRF.objects.prefetch_related('tenant').prefetch_related('tags').annotate(
|
||||
ipaddress_count=get_subquery(IPAddress, 'vrf'),
|
||||
prefix_count=get_subquery(Prefix, 'vrf')
|
||||
)
|
||||
@ -58,7 +58,7 @@ class RIRViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class AggregateViewSet(CustomFieldModelViewSet):
|
||||
queryset = Aggregate.objects.select_related('rir').prefetch_related('tags')
|
||||
queryset = Aggregate.objects.prefetch_related('rir').prefetch_related('tags')
|
||||
serializer_class = serializers.AggregateSerializer
|
||||
filterset_class = filters.AggregateFilter
|
||||
|
||||
@ -81,11 +81,7 @@ class RoleViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class PrefixViewSet(CustomFieldModelViewSet):
|
||||
queryset = Prefix.objects.select_related(
|
||||
'site', 'vrf__tenant', 'tenant', 'vlan', 'role'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
)
|
||||
queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role', 'tags')
|
||||
serializer_class = serializers.PrefixSerializer
|
||||
filterset_class = filters.PrefixFilter
|
||||
|
||||
@ -263,9 +259,8 @@ class PrefixViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class IPAddressViewSet(CustomFieldModelViewSet):
|
||||
queryset = IPAddress.objects.select_related(
|
||||
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device__device_type', 'interface__virtual_machine'
|
||||
).prefetch_related(
|
||||
queryset = IPAddress.objects.prefetch_related(
|
||||
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device__device_type', 'interface__virtual_machine',
|
||||
'nat_outside', 'tags',
|
||||
)
|
||||
serializer_class = serializers.IPAddressSerializer
|
||||
@ -277,7 +272,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class VLANGroupViewSet(ModelViewSet):
|
||||
queryset = VLANGroup.objects.select_related('site').annotate(
|
||||
queryset = VLANGroup.objects.prefetch_related('site').annotate(
|
||||
vlan_count=Count('vlans')
|
||||
)
|
||||
serializer_class = serializers.VLANGroupSerializer
|
||||
@ -289,10 +284,8 @@ class VLANGroupViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class VLANViewSet(CustomFieldModelViewSet):
|
||||
queryset = VLAN.objects.select_related(
|
||||
'site', 'group', 'tenant', 'role'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
queryset = VLAN.objects.prefetch_related(
|
||||
'site', 'group', 'tenant', 'role', 'tags'
|
||||
).annotate(
|
||||
prefix_count=get_subquery(Prefix, 'role')
|
||||
)
|
||||
@ -305,6 +298,6 @@ class VLANViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class ServiceViewSet(ModelViewSet):
|
||||
queryset = Service.objects.select_related('device').prefetch_related('tags')
|
||||
queryset = Service.objects.prefetch_related('device').prefetch_related('tags')
|
||||
serializer_class = serializers.ServiceSerializer
|
||||
filterset_class = filters.ServiceFilter
|
||||
|
@ -360,7 +360,7 @@ class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet):
|
||||
|
||||
def filter_device(self, queryset, name, value):
|
||||
try:
|
||||
device = Device.objects.select_related('device_type').get(**{name: value})
|
||||
device = Device.objects.prefetch_related('device_type').get(**{name: value})
|
||||
vc_interface_ids = [i['id'] for i in device.vc_interfaces.values('id')]
|
||||
return queryset.filter(interface_id__in=vc_interface_ids)
|
||||
except Device.DoesNotExist:
|
||||
|
@ -115,7 +115,7 @@ def add_available_vlans(vlan_group, vlans):
|
||||
|
||||
class VRFListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_vrf'
|
||||
queryset = VRF.objects.select_related('tenant')
|
||||
queryset = VRF.objects.prefetch_related('tenant')
|
||||
filter = filters.VRFFilter
|
||||
filter_form = forms.VRFFilterForm
|
||||
table = tables.VRFTable
|
||||
@ -163,7 +163,7 @@ class VRFBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class VRFBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'ipam.change_vrf'
|
||||
queryset = VRF.objects.select_related('tenant')
|
||||
queryset = VRF.objects.prefetch_related('tenant')
|
||||
filter = filters.VRFFilter
|
||||
table = tables.VRFTable
|
||||
form = forms.VRFBulkEditForm
|
||||
@ -172,7 +172,7 @@ class VRFBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_vrf'
|
||||
queryset = VRF.objects.select_related('tenant')
|
||||
queryset = VRF.objects.prefetch_related('tenant')
|
||||
filter = filters.VRFFilter
|
||||
table = tables.VRFTable
|
||||
default_return_url = 'ipam:vrf_list'
|
||||
@ -291,7 +291,7 @@ class RIRBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class AggregateListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_aggregate'
|
||||
queryset = Aggregate.objects.select_related('rir').extra(select={
|
||||
queryset = Aggregate.objects.prefetch_related('rir').extra(select={
|
||||
'child_count': 'SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix',
|
||||
})
|
||||
filter = filters.AggregateFilter
|
||||
@ -326,7 +326,7 @@ class AggregateView(PermissionRequiredMixin, View):
|
||||
# Find all child prefixes contained by this aggregate
|
||||
child_prefixes = Prefix.objects.filter(
|
||||
prefix__net_contained_or_equal=str(aggregate.prefix)
|
||||
).select_related(
|
||||
).prefetch_related(
|
||||
'site', 'role'
|
||||
).annotate_depth(
|
||||
limit=0
|
||||
@ -384,7 +384,7 @@ class AggregateBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class AggregateBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'ipam.change_aggregate'
|
||||
queryset = Aggregate.objects.select_related('rir')
|
||||
queryset = Aggregate.objects.prefetch_related('rir')
|
||||
filter = filters.AggregateFilter
|
||||
table = tables.AggregateTable
|
||||
form = forms.AggregateBulkEditForm
|
||||
@ -393,7 +393,7 @@ class AggregateBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_aggregate'
|
||||
queryset = Aggregate.objects.select_related('rir')
|
||||
queryset = Aggregate.objects.prefetch_related('rir')
|
||||
filter = filters.AggregateFilter
|
||||
table = tables.AggregateTable
|
||||
default_return_url = 'ipam:aggregate_list'
|
||||
@ -441,7 +441,7 @@ class RoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class PrefixListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_prefix'
|
||||
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||
queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||
filter = filters.PrefixFilter
|
||||
filter_form = forms.PrefixFilterForm
|
||||
table = tables.PrefixDetailTable
|
||||
@ -458,7 +458,7 @@ class PrefixView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
prefix = get_object_or_404(Prefix.objects.select_related(
|
||||
prefix = get_object_or_404(Prefix.objects.prefetch_related(
|
||||
'vrf', 'site__region', 'tenant__group', 'vlan__group', 'role'
|
||||
), pk=pk)
|
||||
|
||||
@ -472,7 +472,7 @@ class PrefixView(PermissionRequiredMixin, View):
|
||||
Q(vrf=prefix.vrf) | Q(vrf__isnull=True)
|
||||
).filter(
|
||||
prefix__net_contains=str(prefix.prefix)
|
||||
).select_related(
|
||||
).prefetch_related(
|
||||
'site', 'role'
|
||||
).annotate_depth()
|
||||
parent_prefix_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
|
||||
@ -483,7 +483,7 @@ class PrefixView(PermissionRequiredMixin, View):
|
||||
vrf=prefix.vrf, prefix=str(prefix.prefix)
|
||||
).exclude(
|
||||
pk=prefix.pk
|
||||
).select_related(
|
||||
).prefetch_related(
|
||||
'site', 'role'
|
||||
)
|
||||
duplicate_prefix_table = tables.PrefixTable(list(duplicate_prefixes), orderable=False)
|
||||
@ -505,7 +505,7 @@ class PrefixPrefixesView(PermissionRequiredMixin, View):
|
||||
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||
|
||||
# Child prefixes table
|
||||
child_prefixes = prefix.get_child_prefixes().select_related(
|
||||
child_prefixes = prefix.get_child_prefixes().prefetch_related(
|
||||
'site', 'vlan', 'role',
|
||||
).annotate_depth(limit=0)
|
||||
|
||||
@ -548,7 +548,7 @@ class PrefixIPAddressesView(PermissionRequiredMixin, View):
|
||||
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||
|
||||
# Find all IPAddresses belonging to this Prefix
|
||||
ipaddresses = prefix.get_child_ips().select_related(
|
||||
ipaddresses = prefix.get_child_ips().prefetch_related(
|
||||
'vrf', 'interface__device', 'primary_ip4_for', 'primary_ip6_for'
|
||||
)
|
||||
ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)
|
||||
@ -608,7 +608,7 @@ class PrefixBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'ipam.change_prefix'
|
||||
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||
queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||
filter = filters.PrefixFilter
|
||||
table = tables.PrefixTable
|
||||
form = forms.PrefixBulkEditForm
|
||||
@ -617,7 +617,7 @@ class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_prefix'
|
||||
queryset = Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||
queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role')
|
||||
filter = filters.PrefixFilter
|
||||
table = tables.PrefixTable
|
||||
default_return_url = 'ipam:prefix_list'
|
||||
@ -629,10 +629,8 @@ class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class IPAddressListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_ipaddress'
|
||||
queryset = IPAddress.objects.select_related(
|
||||
'vrf__tenant', 'tenant', 'nat_inside'
|
||||
).prefetch_related(
|
||||
'interface__device', 'interface__virtual_machine'
|
||||
queryset = IPAddress.objects.prefetch_related(
|
||||
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device', 'interface__virtual_machine'
|
||||
)
|
||||
filter = filters.IPAddressFilter
|
||||
filter_form = forms.IPAddressFilterForm
|
||||
@ -645,12 +643,12 @@ class IPAddressView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
ipaddress = get_object_or_404(IPAddress.objects.select_related('vrf__tenant', 'tenant'), pk=pk)
|
||||
ipaddress = get_object_or_404(IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'), pk=pk)
|
||||
|
||||
# Parent prefixes table
|
||||
parent_prefixes = Prefix.objects.filter(
|
||||
vrf=ipaddress.vrf, prefix__net_contains=str(ipaddress.address.ip)
|
||||
).select_related(
|
||||
).prefetch_related(
|
||||
'site', 'role'
|
||||
)
|
||||
parent_prefixes_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
|
||||
@ -661,10 +659,8 @@ class IPAddressView(PermissionRequiredMixin, View):
|
||||
vrf=ipaddress.vrf, address=str(ipaddress.address)
|
||||
).exclude(
|
||||
pk=ipaddress.pk
|
||||
).select_related(
|
||||
'nat_inside'
|
||||
).prefetch_related(
|
||||
'interface__device'
|
||||
'nat_inside', 'interface__device'
|
||||
)
|
||||
# Exclude anycast IPs if this IP is anycast
|
||||
if ipaddress.role == IPADDRESS_ROLE_ANYCAST:
|
||||
@ -742,7 +738,7 @@ class IPAddressAssignView(PermissionRequiredMixin, View):
|
||||
|
||||
if form.is_valid():
|
||||
|
||||
queryset = IPAddress.objects.select_related(
|
||||
queryset = IPAddress.objects.prefetch_related(
|
||||
'vrf', 'tenant', 'interface__device', 'interface__virtual_machine'
|
||||
).filter(
|
||||
vrf=form.cleaned_data['vrf'],
|
||||
@ -781,7 +777,7 @@ class IPAddressBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'ipam.change_ipaddress'
|
||||
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant').prefetch_related('interface__device')
|
||||
queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant').prefetch_related('interface__device')
|
||||
filter = filters.IPAddressFilter
|
||||
table = tables.IPAddressTable
|
||||
form = forms.IPAddressBulkEditForm
|
||||
@ -790,7 +786,7 @@ class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_ipaddress'
|
||||
queryset = IPAddress.objects.select_related('vrf__tenant', 'tenant').prefetch_related('interface__device')
|
||||
queryset = IPAddress.objects.prefetch_related('vrf__tenant', 'tenant').prefetch_related('interface__device')
|
||||
filter = filters.IPAddressFilter
|
||||
table = tables.IPAddressTable
|
||||
default_return_url = 'ipam:ipaddress_list'
|
||||
@ -802,7 +798,7 @@ class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class VLANGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_vlangroup'
|
||||
queryset = VLANGroup.objects.select_related('site').annotate(vlan_count=Count('vlans'))
|
||||
queryset = VLANGroup.objects.prefetch_related('site').annotate(vlan_count=Count('vlans'))
|
||||
filter = filters.VLANGroupFilter
|
||||
filter_form = forms.VLANGroupFilterForm
|
||||
table = tables.VLANGroupTable
|
||||
@ -829,7 +825,7 @@ class VLANGroupBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class VLANGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_vlangroup'
|
||||
queryset = VLANGroup.objects.select_related('site').annotate(vlan_count=Count('vlans'))
|
||||
queryset = VLANGroup.objects.prefetch_related('site').annotate(vlan_count=Count('vlans'))
|
||||
filter = filters.VLANGroupFilter
|
||||
table = tables.VLANGroupTable
|
||||
default_return_url = 'ipam:vlangroup_list'
|
||||
@ -878,7 +874,7 @@ class VLANGroupVLANsView(PermissionRequiredMixin, View):
|
||||
|
||||
class VLANListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_vlan'
|
||||
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role').prefetch_related('prefixes')
|
||||
queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role').prefetch_related('prefixes')
|
||||
filter = filters.VLANFilter
|
||||
filter_form = forms.VLANFilterForm
|
||||
table = tables.VLANDetailTable
|
||||
@ -890,10 +886,10 @@ class VLANView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
vlan = get_object_or_404(VLAN.objects.select_related(
|
||||
vlan = get_object_or_404(VLAN.objects.prefetch_related(
|
||||
'site__region', 'tenant__group', 'role'
|
||||
), pk=pk)
|
||||
prefixes = Prefix.objects.filter(vlan=vlan).select_related('vrf', 'site', 'role')
|
||||
prefixes = Prefix.objects.filter(vlan=vlan).prefetch_related('vrf', 'site', 'role')
|
||||
prefix_table = tables.PrefixTable(list(prefixes), orderable=False)
|
||||
prefix_table.exclude = ('vlan',)
|
||||
|
||||
@ -909,7 +905,7 @@ class VLANMembersView(PermissionRequiredMixin, View):
|
||||
def get(self, request, pk):
|
||||
|
||||
vlan = get_object_or_404(VLAN.objects.all(), pk=pk)
|
||||
members = vlan.get_members().select_related('device', 'virtual_machine')
|
||||
members = vlan.get_members().prefetch_related('device', 'virtual_machine')
|
||||
|
||||
members_table = tables.VLANMemberTable(members)
|
||||
|
||||
@ -953,7 +949,7 @@ class VLANBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class VLANBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'ipam.change_vlan'
|
||||
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role')
|
||||
queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role')
|
||||
filter = filters.VLANFilter
|
||||
table = tables.VLANTable
|
||||
form = forms.VLANBulkEditForm
|
||||
@ -962,7 +958,7 @@ class VLANBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_vlan'
|
||||
queryset = VLAN.objects.select_related('site', 'group', 'tenant', 'role')
|
||||
queryset = VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role')
|
||||
filter = filters.VLANFilter
|
||||
table = tables.VLANTable
|
||||
default_return_url = 'ipam:vlan_list'
|
||||
@ -974,7 +970,7 @@ class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class ServiceListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'ipam.view_service'
|
||||
queryset = Service.objects.select_related('device', 'virtual_machine')
|
||||
queryset = Service.objects.prefetch_related('device', 'virtual_machine')
|
||||
filter = filters.ServiceFilter
|
||||
filter_form = forms.ServiceFilterForm
|
||||
table = tables.ServiceTable
|
||||
@ -1021,7 +1017,7 @@ class ServiceDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
||||
|
||||
class ServiceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'ipam.change_service'
|
||||
queryset = Service.objects.select_related('device', 'virtual_machine')
|
||||
queryset = Service.objects.prefetch_related('device', 'virtual_machine')
|
||||
filter = filters.ServiceFilter
|
||||
table = tables.ServiceTable
|
||||
form = forms.ServiceBulkEditForm
|
||||
@ -1030,7 +1026,7 @@ class ServiceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class ServiceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'ipam.delete_service'
|
||||
queryset = Service.objects.select_related('device', 'virtual_machine')
|
||||
queryset = Service.objects.prefetch_related('device', 'virtual_machine')
|
||||
filter = filters.ServiceFilter
|
||||
table = tables.ServiceTable
|
||||
default_return_url = 'ipam:service_list'
|
||||
|
@ -37,7 +37,7 @@ class TokenAuthentication(authentication.TokenAuthentication):
|
||||
def authenticate_credentials(self, key):
|
||||
model = self.get_model()
|
||||
try:
|
||||
token = model.objects.select_related('user').get(key=key)
|
||||
token = model.objects.prefetch_related('user').get(key=key)
|
||||
except model.DoesNotExist:
|
||||
raise exceptions.AuthenticationFailed("Invalid token")
|
||||
|
||||
|
@ -46,38 +46,38 @@ SEARCH_TYPES = OrderedDict((
|
||||
'url': 'circuits:provider_list',
|
||||
}),
|
||||
('circuit', {
|
||||
'queryset': Circuit.objects.select_related('type', 'provider', 'tenant').prefetch_related('terminations__site'),
|
||||
'queryset': Circuit.objects.prefetch_related('type', 'provider', 'tenant').prefetch_related('terminations__site'),
|
||||
'filter': CircuitFilter,
|
||||
'table': CircuitTable,
|
||||
'url': 'circuits:circuit_list',
|
||||
}),
|
||||
# DCIM
|
||||
('site', {
|
||||
'queryset': Site.objects.select_related('region', 'tenant'),
|
||||
'queryset': Site.objects.prefetch_related('region', 'tenant'),
|
||||
'filter': SiteFilter,
|
||||
'table': SiteTable,
|
||||
'url': 'dcim:site_list',
|
||||
}),
|
||||
('rack', {
|
||||
'queryset': Rack.objects.select_related('site', 'group', 'tenant', 'role'),
|
||||
'queryset': Rack.objects.prefetch_related('site', 'group', 'tenant', 'role'),
|
||||
'filter': RackFilter,
|
||||
'table': RackTable,
|
||||
'url': 'dcim:rack_list',
|
||||
}),
|
||||
('rackgroup', {
|
||||
'queryset': RackGroup.objects.select_related('site').annotate(rack_count=Count('racks')),
|
||||
'queryset': RackGroup.objects.prefetch_related('site').annotate(rack_count=Count('racks')),
|
||||
'filter': RackGroupFilter,
|
||||
'table': RackGroupTable,
|
||||
'url': 'dcim:rackgroup_list',
|
||||
}),
|
||||
('devicetype', {
|
||||
'queryset': DeviceType.objects.select_related('manufacturer').annotate(instance_count=Count('instances')),
|
||||
'queryset': DeviceType.objects.prefetch_related('manufacturer').annotate(instance_count=Count('instances')),
|
||||
'filter': DeviceTypeFilter,
|
||||
'table': DeviceTypeTable,
|
||||
'url': 'dcim:devicetype_list',
|
||||
}),
|
||||
('device', {
|
||||
'queryset': Device.objects.select_related(
|
||||
'queryset': Device.objects.prefetch_related(
|
||||
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6',
|
||||
),
|
||||
'filter': DeviceFilter,
|
||||
@ -85,7 +85,7 @@ SEARCH_TYPES = OrderedDict((
|
||||
'url': 'dcim:device_list',
|
||||
}),
|
||||
('virtualchassis', {
|
||||
'queryset': VirtualChassis.objects.select_related('master').annotate(member_count=Count('members')),
|
||||
'queryset': VirtualChassis.objects.prefetch_related('master').annotate(member_count=Count('members')),
|
||||
'filter': VirtualChassisFilter,
|
||||
'table': VirtualChassisTable,
|
||||
'url': 'dcim:virtualchassis_list',
|
||||
@ -104,58 +104,58 @@ SEARCH_TYPES = OrderedDict((
|
||||
}),
|
||||
# IPAM
|
||||
('vrf', {
|
||||
'queryset': VRF.objects.select_related('tenant'),
|
||||
'queryset': VRF.objects.prefetch_related('tenant'),
|
||||
'filter': VRFFilter,
|
||||
'table': VRFTable,
|
||||
'url': 'ipam:vrf_list',
|
||||
}),
|
||||
('aggregate', {
|
||||
'queryset': Aggregate.objects.select_related('rir'),
|
||||
'queryset': Aggregate.objects.prefetch_related('rir'),
|
||||
'filter': AggregateFilter,
|
||||
'table': AggregateTable,
|
||||
'url': 'ipam:aggregate_list',
|
||||
}),
|
||||
('prefix', {
|
||||
'queryset': Prefix.objects.select_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role'),
|
||||
'queryset': Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role'),
|
||||
'filter': PrefixFilter,
|
||||
'table': PrefixTable,
|
||||
'url': 'ipam:prefix_list',
|
||||
}),
|
||||
('ipaddress', {
|
||||
'queryset': IPAddress.objects.select_related('vrf__tenant', 'tenant'),
|
||||
'queryset': IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'),
|
||||
'filter': IPAddressFilter,
|
||||
'table': IPAddressTable,
|
||||
'url': 'ipam:ipaddress_list',
|
||||
}),
|
||||
('vlan', {
|
||||
'queryset': VLAN.objects.select_related('site', 'group', 'tenant', 'role'),
|
||||
'queryset': VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role'),
|
||||
'filter': VLANFilter,
|
||||
'table': VLANTable,
|
||||
'url': 'ipam:vlan_list',
|
||||
}),
|
||||
# Secrets
|
||||
('secret', {
|
||||
'queryset': Secret.objects.select_related('role', 'device'),
|
||||
'queryset': Secret.objects.prefetch_related('role', 'device'),
|
||||
'filter': SecretFilter,
|
||||
'table': SecretTable,
|
||||
'url': 'secrets:secret_list',
|
||||
}),
|
||||
# Tenancy
|
||||
('tenant', {
|
||||
'queryset': Tenant.objects.select_related('group'),
|
||||
'queryset': Tenant.objects.prefetch_related('group'),
|
||||
'filter': TenantFilter,
|
||||
'table': TenantTable,
|
||||
'url': 'tenancy:tenant_list',
|
||||
}),
|
||||
# Virtualization
|
||||
('cluster', {
|
||||
'queryset': Cluster.objects.select_related('type', 'group'),
|
||||
'queryset': Cluster.objects.prefetch_related('type', 'group'),
|
||||
'filter': ClusterFilter,
|
||||
'table': ClusterTable,
|
||||
'url': 'virtualization:cluster_list',
|
||||
}),
|
||||
('virtualmachine', {
|
||||
'queryset': VirtualMachine.objects.select_related(
|
||||
'queryset': VirtualMachine.objects.prefetch_related(
|
||||
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
|
||||
),
|
||||
'filter': VirtualMachineFilter,
|
||||
@ -224,7 +224,7 @@ class HomeView(View):
|
||||
'stats': stats,
|
||||
'topology_maps': TopologyMap.objects.filter(site__isnull=True),
|
||||
'report_results': ReportResult.objects.order_by('-created')[:10],
|
||||
'changelog': ObjectChange.objects.select_related('user', 'changed_object_type')[:50]
|
||||
'changelog': ObjectChange.objects.prefetch_related('user', 'changed_object_type')[:50]
|
||||
})
|
||||
|
||||
|
||||
|
@ -46,10 +46,8 @@ class SecretRoleViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class SecretViewSet(ModelViewSet):
|
||||
queryset = Secret.objects.select_related(
|
||||
'device__primary_ip4', 'device__primary_ip6', 'role',
|
||||
).prefetch_related(
|
||||
'role__users', 'role__groups', 'tags',
|
||||
queryset = Secret.objects.prefetch_related(
|
||||
'device__primary_ip4', 'device__primary_ip6', 'role', 'role__users', 'role__groups', 'tags',
|
||||
)
|
||||
serializer_class = serializers.SecretSerializer
|
||||
filterset_class = filters.SecretFilter
|
||||
|
@ -69,7 +69,7 @@ class SecretRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class SecretListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'secrets.view_secret'
|
||||
queryset = Secret.objects.select_related('role', 'device')
|
||||
queryset = Secret.objects.prefetch_related('role', 'device')
|
||||
filter = filters.SecretFilter
|
||||
filter_form = forms.SecretFilterForm
|
||||
table = tables.SecretTable
|
||||
@ -247,7 +247,7 @@ class SecretBulkImportView(BulkImportView):
|
||||
|
||||
class SecretBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'secrets.change_secret'
|
||||
queryset = Secret.objects.select_related('role', 'device')
|
||||
queryset = Secret.objects.prefetch_related('role', 'device')
|
||||
filter = filters.SecretFilter
|
||||
table = tables.SecretTable
|
||||
form = forms.SecretBulkEditForm
|
||||
@ -256,7 +256,7 @@ class SecretBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class SecretBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'secrets.delete_secret'
|
||||
queryset = Secret.objects.select_related('role', 'device')
|
||||
queryset = Secret.objects.prefetch_related('role', 'device')
|
||||
filter = filters.SecretFilter
|
||||
table = tables.SecretTable
|
||||
default_return_url = 'secrets:secret_list'
|
||||
|
@ -35,10 +35,8 @@ class TenantGroupViewSet(ModelViewSet):
|
||||
#
|
||||
|
||||
class TenantViewSet(CustomFieldModelViewSet):
|
||||
queryset = Tenant.objects.select_related(
|
||||
'group'
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
queryset = Tenant.objects.prefetch_related(
|
||||
'group', 'tags'
|
||||
).annotate(
|
||||
circuit_count=get_subquery(Circuit, 'tenant'),
|
||||
device_count=get_subquery(Device, 'tenant'),
|
||||
|
@ -56,7 +56,7 @@ class TenantGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class TenantListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'tenancy.view_tenant'
|
||||
queryset = Tenant.objects.select_related('group')
|
||||
queryset = Tenant.objects.prefetch_related('group')
|
||||
filter = filters.TenantFilter
|
||||
filter_form = forms.TenantFilterForm
|
||||
table = tables.TenantTable
|
||||
@ -115,7 +115,7 @@ class TenantBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class TenantBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'tenancy.change_tenant'
|
||||
queryset = Tenant.objects.select_related('group')
|
||||
queryset = Tenant.objects.prefetch_related('group')
|
||||
filter = filters.TenantFilter
|
||||
table = tables.TenantTable
|
||||
form = forms.TenantBulkEditForm
|
||||
@ -124,7 +124,7 @@ class TenantBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class TenantBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'tenancy.delete_tenant'
|
||||
queryset = Tenant.objects.select_related('group')
|
||||
queryset = Tenant.objects.prefetch_related('group')
|
||||
filter = filters.TenantFilter
|
||||
table = tables.TenantTable
|
||||
default_return_url = 'tenancy:tenant_list'
|
||||
|
@ -40,10 +40,8 @@ class ClusterGroupViewSet(ModelViewSet):
|
||||
|
||||
|
||||
class ClusterViewSet(CustomFieldModelViewSet):
|
||||
queryset = Cluster.objects.select_related(
|
||||
'type', 'group', 'site',
|
||||
).prefetch_related(
|
||||
'tags'
|
||||
queryset = Cluster.objects.prefetch_related(
|
||||
'type', 'group', 'site', 'tags'
|
||||
).annotate(
|
||||
device_count=get_subquery(Device, 'cluster'),
|
||||
virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
|
||||
@ -57,9 +55,9 @@ class ClusterViewSet(CustomFieldModelViewSet):
|
||||
#
|
||||
|
||||
class VirtualMachineViewSet(CustomFieldModelViewSet):
|
||||
queryset = VirtualMachine.objects.select_related(
|
||||
'cluster__site', 'role', 'tenant', 'platform', 'primary_ip4', 'primary_ip6'
|
||||
).prefetch_related('tags')
|
||||
queryset = VirtualMachine.objects.prefetch_related(
|
||||
'cluster__site', 'role', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'tags'
|
||||
)
|
||||
filterset_class = filters.VirtualMachineFilter
|
||||
|
||||
def get_serializer_class(self):
|
||||
@ -86,7 +84,9 @@ class VirtualMachineViewSet(CustomFieldModelViewSet):
|
||||
class InterfaceViewSet(ModelViewSet):
|
||||
queryset = Interface.objects.filter(
|
||||
virtual_machine__isnull=False
|
||||
).select_related('virtual_machine').prefetch_related('tags')
|
||||
).prefetch_related(
|
||||
'virtual_machine', 'tags'
|
||||
)
|
||||
serializer_class = serializers.InterfaceSerializer
|
||||
filterset_class = filters.InterfaceFilter
|
||||
|
||||
|
@ -376,7 +376,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
for family in [4, 6]:
|
||||
ip_choices = [(None, '---------')]
|
||||
# Collect interface IPs
|
||||
interface_ips = IPAddress.objects.select_related('interface').filter(
|
||||
interface_ips = IPAddress.objects.prefetch_related('interface').filter(
|
||||
family=family, interface__virtual_machine=self.instance
|
||||
)
|
||||
if interface_ips:
|
||||
@ -386,7 +386,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
||||
])
|
||||
)
|
||||
# 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__virtual_machine=self.instance
|
||||
)
|
||||
if nat_ips:
|
||||
|
@ -96,7 +96,7 @@ class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
|
||||
class ClusterListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'virtualization.view_cluster'
|
||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
||||
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||
table = tables.ClusterTable
|
||||
filter = filters.ClusterFilter
|
||||
filter_form = forms.ClusterFilterForm
|
||||
@ -109,7 +109,7 @@ class ClusterView(PermissionRequiredMixin, View):
|
||||
def get(self, request, pk):
|
||||
|
||||
cluster = get_object_or_404(Cluster, pk=pk)
|
||||
devices = Device.objects.filter(cluster=cluster).select_related(
|
||||
devices = Device.objects.filter(cluster=cluster).prefetch_related(
|
||||
'site', 'rack', 'tenant', 'device_type__manufacturer'
|
||||
)
|
||||
device_table = DeviceTable(list(devices), orderable=False)
|
||||
@ -148,7 +148,7 @@ class ClusterBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'virtualization.change_cluster'
|
||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
||||
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||
filter = filters.ClusterFilter
|
||||
table = tables.ClusterTable
|
||||
form = forms.ClusterBulkEditForm
|
||||
@ -157,7 +157,7 @@ class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'virtualization.delete_cluster'
|
||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
||||
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||
filter = filters.ClusterFilter
|
||||
table = tables.ClusterTable
|
||||
default_return_url = 'virtualization:cluster_list'
|
||||
@ -253,7 +253,7 @@ class ClusterRemoveDevicesView(PermissionRequiredMixin, View):
|
||||
|
||||
class VirtualMachineListView(PermissionRequiredMixin, ObjectListView):
|
||||
permission_required = 'virtualization.view_virtualmachine'
|
||||
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role', 'primary_ip4', 'primary_ip6')
|
||||
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role', 'primary_ip4', 'primary_ip6')
|
||||
filter = filters.VirtualMachineFilter
|
||||
filter_form = forms.VirtualMachineFilterForm
|
||||
table = tables.VirtualMachineDetailTable
|
||||
@ -265,7 +265,7 @@ class VirtualMachineView(PermissionRequiredMixin, View):
|
||||
|
||||
def get(self, request, pk):
|
||||
|
||||
virtualmachine = get_object_or_404(VirtualMachine.objects.select_related('tenant__group'), pk=pk)
|
||||
virtualmachine = get_object_or_404(VirtualMachine.objects.prefetch_related('tenant__group'), pk=pk)
|
||||
interfaces = Interface.objects.filter(virtual_machine=virtualmachine)
|
||||
services = Service.objects.filter(virtual_machine=virtualmachine)
|
||||
|
||||
@ -309,7 +309,7 @@ class VirtualMachineBulkImportView(PermissionRequiredMixin, BulkImportView):
|
||||
|
||||
class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
permission_required = 'virtualization.change_virtualmachine'
|
||||
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role')
|
||||
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role')
|
||||
filter = filters.VirtualMachineFilter
|
||||
table = tables.VirtualMachineTable
|
||||
form = forms.VirtualMachineBulkEditForm
|
||||
@ -318,7 +318,7 @@ class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||
|
||||
class VirtualMachineBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||
permission_required = 'virtualization.delete_virtualmachine'
|
||||
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role')
|
||||
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role')
|
||||
filter = filters.VirtualMachineFilter
|
||||
table = tables.VirtualMachineTable
|
||||
default_return_url = 'virtualization:virtualmachine_list'
|
||||
|
Loading…
Reference in New Issue
Block a user