mirror of
https://github.com/netbox-community/netbox.git
synced 2025-07-14 09:51: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):
|
def test_console_connection(self):
|
||||||
|
|
||||||
# Check that every console port for every active device has a connection defined.
|
# 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:
|
if console_port.connected_endpoint is None:
|
||||||
self.log_failure(
|
self.log_failure(
|
||||||
console_port.device,
|
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
|
### 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
|
### 5. Update API serializer
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ class CircuitTypeViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class CircuitViewSet(CustomFieldModelViewSet):
|
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
|
serializer_class = serializers.CircuitSerializer
|
||||||
filterset_class = filters.CircuitFilter
|
filterset_class = filters.CircuitFilter
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ class CircuitViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class CircuitTerminationViewSet(ModelViewSet):
|
class CircuitTerminationViewSet(ModelViewSet):
|
||||||
queryset = CircuitTermination.objects.select_related(
|
queryset = CircuitTermination.objects.prefetch_related(
|
||||||
'circuit', 'site', 'connected_endpoint__device', 'cable'
|
'circuit', 'site', 'connected_endpoint__device', 'cable'
|
||||||
)
|
)
|
||||||
serializer_class = serializers.CircuitTerminationSerializer
|
serializer_class = serializers.CircuitTerminationSerializer
|
||||||
|
@ -295,6 +295,6 @@ class CircuitTermination(CableTermination):
|
|||||||
def get_peer_termination(self):
|
def get_peer_termination(self):
|
||||||
peer_side = 'Z' if self.term_side == 'A' else 'A'
|
peer_side = 'Z' if self.term_side == 'A' else 'A'
|
||||||
try:
|
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:
|
except CircuitTermination.DoesNotExist:
|
||||||
return None
|
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.
|
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):
|
def get(self, request, slug):
|
||||||
|
|
||||||
provider = get_object_or_404(Provider, slug=slug)
|
provider = get_object_or_404(Provider, slug=slug)
|
||||||
circuits = Circuit.objects.filter(provider=provider).select_related(
|
circuits = Circuit.objects.filter(provider=provider).prefetch_related('type', 'tenant', 'terminations__site')
|
||||||
'type', 'tenant'
|
|
||||||
).prefetch_related(
|
|
||||||
'terminations__site'
|
|
||||||
)
|
|
||||||
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
|
show_graphs = Graph.objects.filter(type=GRAPH_TYPE_PROVIDER).exists()
|
||||||
|
|
||||||
return render(request, 'circuits/provider.html', {
|
return render(request, 'circuits/provider.html', {
|
||||||
@ -134,10 +130,8 @@ class CircuitTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
class CircuitListView(PermissionRequiredMixin, ObjectListView):
|
class CircuitListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'circuits.view_circuit'
|
permission_required = 'circuits.view_circuit'
|
||||||
_terminations = CircuitTermination.objects.filter(circuit=OuterRef('pk'))
|
_terminations = CircuitTermination.objects.filter(circuit=OuterRef('pk'))
|
||||||
queryset = Circuit.objects.select_related(
|
queryset = Circuit.objects.prefetch_related(
|
||||||
'provider', 'type', 'tenant'
|
'provider', 'type', 'tenant', 'terminations__site'
|
||||||
).prefetch_related(
|
|
||||||
'terminations__site'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
a_side=Subquery(_terminations.filter(term_side='A').values('site__name')[:1]),
|
a_side=Subquery(_terminations.filter(term_side='A').values('site__name')[:1]),
|
||||||
z_side=Subquery(_terminations.filter(term_side='Z').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):
|
def get(self, request, pk):
|
||||||
|
|
||||||
circuit = get_object_or_404(Circuit.objects.select_related('provider', 'type', 'tenant__group'), pk=pk)
|
circuit = get_object_or_404(Circuit.objects.prefetch_related('provider', 'type', 'tenant__group'), pk=pk)
|
||||||
termination_a = CircuitTermination.objects.select_related(
|
termination_a = CircuitTermination.objects.prefetch_related(
|
||||||
'site__region', 'connected_endpoint__device'
|
'site__region', 'connected_endpoint__device'
|
||||||
).filter(
|
).filter(
|
||||||
circuit=circuit, term_side=TERM_SIDE_A
|
circuit=circuit, term_side=TERM_SIDE_A
|
||||||
).first()
|
).first()
|
||||||
termination_z = CircuitTermination.objects.select_related(
|
termination_z = CircuitTermination.objects.prefetch_related(
|
||||||
'site__region', 'connected_endpoint__device'
|
'site__region', 'connected_endpoint__device'
|
||||||
).filter(
|
).filter(
|
||||||
circuit=circuit, term_side=TERM_SIDE_Z
|
circuit=circuit, term_side=TERM_SIDE_Z
|
||||||
@ -199,7 +193,7 @@ class CircuitBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'circuits.change_circuit'
|
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
|
filter = filters.CircuitFilter
|
||||||
table = tables.CircuitTable
|
table = tables.CircuitTable
|
||||||
form = forms.CircuitBulkEditForm
|
form = forms.CircuitBulkEditForm
|
||||||
@ -208,7 +202,7 @@ class CircuitBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class CircuitBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'circuits.delete_circuit'
|
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
|
filter = filters.CircuitFilter
|
||||||
table = tables.CircuitTable
|
table = tables.CircuitTable
|
||||||
default_return_url = 'circuits:circuit_list'
|
default_return_url = 'circuits:circuit_list'
|
||||||
|
@ -109,10 +109,8 @@ class RegionViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class SiteViewSet(CustomFieldModelViewSet):
|
class SiteViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Site.objects.select_related(
|
queryset = Site.objects.prefetch_related(
|
||||||
'region', 'tenant'
|
'region', 'tenant', 'tags'
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=get_subquery(Device, 'site'),
|
device_count=get_subquery(Device, 'site'),
|
||||||
rack_count=get_subquery(Rack, 'site'),
|
rack_count=get_subquery(Rack, 'site'),
|
||||||
@ -140,7 +138,7 @@ class SiteViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class RackGroupViewSet(ModelViewSet):
|
class RackGroupViewSet(ModelViewSet):
|
||||||
queryset = RackGroup.objects.select_related('site').annotate(
|
queryset = RackGroup.objects.prefetch_related('site').annotate(
|
||||||
rack_count=Count('racks')
|
rack_count=Count('racks')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.RackGroupSerializer
|
serializer_class = serializers.RackGroupSerializer
|
||||||
@ -164,10 +162,8 @@ class RackRoleViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class RackViewSet(CustomFieldModelViewSet):
|
class RackViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Rack.objects.select_related(
|
queryset = Rack.objects.prefetch_related(
|
||||||
'site', 'group__site', 'role', 'tenant'
|
'site', 'group__site', 'role', 'tenant', 'tags'
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=get_subquery(Device, 'rack'),
|
device_count=get_subquery(Device, 'rack'),
|
||||||
powerfeed_count=get_subquery(PowerFeed, 'rack')
|
powerfeed_count=get_subquery(PowerFeed, 'rack')
|
||||||
@ -206,7 +202,7 @@ class RackViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class RackReservationViewSet(ModelViewSet):
|
class RackReservationViewSet(ModelViewSet):
|
||||||
queryset = RackReservation.objects.select_related('rack', 'user', 'tenant')
|
queryset = RackReservation.objects.prefetch_related('rack', 'user', 'tenant')
|
||||||
serializer_class = serializers.RackReservationSerializer
|
serializer_class = serializers.RackReservationSerializer
|
||||||
filterset_class = filters.RackReservationFilter
|
filterset_class = filters.RackReservationFilter
|
||||||
|
|
||||||
@ -234,7 +230,7 @@ class ManufacturerViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class DeviceTypeViewSet(CustomFieldModelViewSet):
|
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')
|
device_count=Count('instances')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.DeviceTypeSerializer
|
serializer_class = serializers.DeviceTypeSerializer
|
||||||
@ -246,49 +242,49 @@ class DeviceTypeViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ConsolePortTemplateViewSet(ModelViewSet):
|
class ConsolePortTemplateViewSet(ModelViewSet):
|
||||||
queryset = ConsolePortTemplate.objects.select_related('device_type__manufacturer')
|
queryset = ConsolePortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.ConsolePortTemplateSerializer
|
serializer_class = serializers.ConsolePortTemplateSerializer
|
||||||
filterset_class = filters.ConsolePortTemplateFilter
|
filterset_class = filters.ConsolePortTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class ConsoleServerPortTemplateViewSet(ModelViewSet):
|
class ConsoleServerPortTemplateViewSet(ModelViewSet):
|
||||||
queryset = ConsoleServerPortTemplate.objects.select_related('device_type__manufacturer')
|
queryset = ConsoleServerPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.ConsoleServerPortTemplateSerializer
|
serializer_class = serializers.ConsoleServerPortTemplateSerializer
|
||||||
filterset_class = filters.ConsoleServerPortTemplateFilter
|
filterset_class = filters.ConsoleServerPortTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class PowerPortTemplateViewSet(ModelViewSet):
|
class PowerPortTemplateViewSet(ModelViewSet):
|
||||||
queryset = PowerPortTemplate.objects.select_related('device_type__manufacturer')
|
queryset = PowerPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.PowerPortTemplateSerializer
|
serializer_class = serializers.PowerPortTemplateSerializer
|
||||||
filterset_class = filters.PowerPortTemplateFilter
|
filterset_class = filters.PowerPortTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class PowerOutletTemplateViewSet(ModelViewSet):
|
class PowerOutletTemplateViewSet(ModelViewSet):
|
||||||
queryset = PowerOutletTemplate.objects.select_related('device_type__manufacturer')
|
queryset = PowerOutletTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.PowerOutletTemplateSerializer
|
serializer_class = serializers.PowerOutletTemplateSerializer
|
||||||
filterset_class = filters.PowerOutletTemplateFilter
|
filterset_class = filters.PowerOutletTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class InterfaceTemplateViewSet(ModelViewSet):
|
class InterfaceTemplateViewSet(ModelViewSet):
|
||||||
queryset = InterfaceTemplate.objects.select_related('device_type__manufacturer')
|
queryset = InterfaceTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.InterfaceTemplateSerializer
|
serializer_class = serializers.InterfaceTemplateSerializer
|
||||||
filterset_class = filters.InterfaceTemplateFilter
|
filterset_class = filters.InterfaceTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class FrontPortTemplateViewSet(ModelViewSet):
|
class FrontPortTemplateViewSet(ModelViewSet):
|
||||||
queryset = FrontPortTemplate.objects.select_related('device_type__manufacturer')
|
queryset = FrontPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.FrontPortTemplateSerializer
|
serializer_class = serializers.FrontPortTemplateSerializer
|
||||||
filterset_class = filters.FrontPortTemplateFilter
|
filterset_class = filters.FrontPortTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class RearPortTemplateViewSet(ModelViewSet):
|
class RearPortTemplateViewSet(ModelViewSet):
|
||||||
queryset = RearPortTemplate.objects.select_related('device_type__manufacturer')
|
queryset = RearPortTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.RearPortTemplateSerializer
|
serializer_class = serializers.RearPortTemplateSerializer
|
||||||
filterset_class = filters.RearPortTemplateFilter
|
filterset_class = filters.RearPortTemplateFilter
|
||||||
|
|
||||||
|
|
||||||
class DeviceBayTemplateViewSet(ModelViewSet):
|
class DeviceBayTemplateViewSet(ModelViewSet):
|
||||||
queryset = DeviceBayTemplate.objects.select_related('device_type__manufacturer')
|
queryset = DeviceBayTemplate.objects.prefetch_related('device_type__manufacturer')
|
||||||
serializer_class = serializers.DeviceBayTemplateSerializer
|
serializer_class = serializers.DeviceBayTemplateSerializer
|
||||||
filterset_class = filters.DeviceBayTemplateFilter
|
filterset_class = filters.DeviceBayTemplateFilter
|
||||||
|
|
||||||
@ -324,11 +320,9 @@ class PlatformViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class DeviceViewSet(CustomFieldModelViewSet):
|
class DeviceViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Device.objects.select_related(
|
queryset = Device.objects.prefetch_related(
|
||||||
'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay',
|
'device_type__manufacturer', 'device_role', 'tenant', 'platform', 'site', 'rack', 'parent_bay',
|
||||||
'virtual_chassis__master',
|
'virtual_chassis__master', 'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
||||||
).prefetch_related(
|
|
||||||
'primary_ip4__nat_outside', 'primary_ip6__nat_outside', 'tags',
|
|
||||||
)
|
)
|
||||||
filterset_class = filters.DeviceFilter
|
filterset_class = filters.DeviceFilter
|
||||||
|
|
||||||
@ -429,52 +423,36 @@ class DeviceViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ConsolePortViewSet(CableTraceMixin, ModelViewSet):
|
class ConsolePortViewSet(CableTraceMixin, ModelViewSet):
|
||||||
queryset = ConsolePort.objects.select_related(
|
queryset = ConsolePort.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
|
||||||
'device', 'connected_endpoint__device', 'cable'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.ConsolePortSerializer
|
serializer_class = serializers.ConsolePortSerializer
|
||||||
filterset_class = filters.ConsolePortFilter
|
filterset_class = filters.ConsolePortFilter
|
||||||
|
|
||||||
|
|
||||||
class ConsoleServerPortViewSet(CableTraceMixin, ModelViewSet):
|
class ConsoleServerPortViewSet(CableTraceMixin, ModelViewSet):
|
||||||
queryset = ConsoleServerPort.objects.select_related(
|
queryset = ConsoleServerPort.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
|
||||||
'device', 'connected_endpoint__device', 'cable'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.ConsoleServerPortSerializer
|
serializer_class = serializers.ConsoleServerPortSerializer
|
||||||
filterset_class = filters.ConsoleServerPortFilter
|
filterset_class = filters.ConsoleServerPortFilter
|
||||||
|
|
||||||
|
|
||||||
class PowerPortViewSet(CableTraceMixin, ModelViewSet):
|
class PowerPortViewSet(CableTraceMixin, ModelViewSet):
|
||||||
queryset = PowerPort.objects.select_related(
|
queryset = PowerPort.objects.prefetch_related(
|
||||||
'device', '_connected_poweroutlet__device', '_connected_powerfeed', 'cable'
|
'device', '_connected_poweroutlet__device', '_connected_powerfeed', 'cable', 'tags'
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
)
|
||||||
serializer_class = serializers.PowerPortSerializer
|
serializer_class = serializers.PowerPortSerializer
|
||||||
filterset_class = filters.PowerPortFilter
|
filterset_class = filters.PowerPortFilter
|
||||||
|
|
||||||
|
|
||||||
class PowerOutletViewSet(CableTraceMixin, ModelViewSet):
|
class PowerOutletViewSet(CableTraceMixin, ModelViewSet):
|
||||||
queryset = PowerOutlet.objects.select_related(
|
queryset = PowerOutlet.objects.prefetch_related('device', 'connected_endpoint__device', 'cable', 'tags')
|
||||||
'device', 'connected_endpoint__device', 'cable'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.PowerOutletSerializer
|
serializer_class = serializers.PowerOutletSerializer
|
||||||
filterset_class = filters.PowerOutletFilter
|
filterset_class = filters.PowerOutletFilter
|
||||||
|
|
||||||
|
|
||||||
class InterfaceViewSet(CableTraceMixin, ModelViewSet):
|
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
|
device__isnull=False
|
||||||
).select_related(
|
|
||||||
'device', '_connected_interface', '_connected_circuittermination', 'cable'
|
|
||||||
).prefetch_related(
|
|
||||||
'ip_addresses', 'tags'
|
|
||||||
)
|
)
|
||||||
serializer_class = serializers.InterfaceSerializer
|
serializer_class = serializers.InterfaceSerializer
|
||||||
filterset_class = filters.InterfaceFilter
|
filterset_class = filters.InterfaceFilter
|
||||||
@ -491,33 +469,25 @@ class InterfaceViewSet(CableTraceMixin, ModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class FrontPortViewSet(ModelViewSet):
|
class FrontPortViewSet(ModelViewSet):
|
||||||
queryset = FrontPort.objects.select_related(
|
queryset = FrontPort.objects.prefetch_related('device__device_type__manufacturer', 'rear_port', 'cable', 'tags')
|
||||||
'device__device_type__manufacturer', 'rear_port', 'cable'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.FrontPortSerializer
|
serializer_class = serializers.FrontPortSerializer
|
||||||
filterset_class = filters.FrontPortFilter
|
filterset_class = filters.FrontPortFilter
|
||||||
|
|
||||||
|
|
||||||
class RearPortViewSet(ModelViewSet):
|
class RearPortViewSet(ModelViewSet):
|
||||||
queryset = RearPort.objects.select_related(
|
queryset = RearPort.objects.prefetch_related('device__device_type__manufacturer', 'cable', 'tags')
|
||||||
'device__device_type__manufacturer', 'cable'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.RearPortSerializer
|
serializer_class = serializers.RearPortSerializer
|
||||||
filterset_class = filters.RearPortFilter
|
filterset_class = filters.RearPortFilter
|
||||||
|
|
||||||
|
|
||||||
class DeviceBayViewSet(ModelViewSet):
|
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
|
serializer_class = serializers.DeviceBaySerializer
|
||||||
filterset_class = filters.DeviceBayFilter
|
filterset_class = filters.DeviceBayFilter
|
||||||
|
|
||||||
|
|
||||||
class InventoryItemViewSet(ModelViewSet):
|
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
|
serializer_class = serializers.InventoryItemSerializer
|
||||||
filterset_class = filters.InventoryItemFilter
|
filterset_class = filters.InventoryItemFilter
|
||||||
|
|
||||||
@ -527,7 +497,7 @@ class InventoryItemViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
|
class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||||
queryset = ConsolePort.objects.select_related(
|
queryset = ConsolePort.objects.prefetch_related(
|
||||||
'device', 'connected_endpoint__device'
|
'device', 'connected_endpoint__device'
|
||||||
).filter(
|
).filter(
|
||||||
connected_endpoint__isnull=False
|
connected_endpoint__isnull=False
|
||||||
@ -537,7 +507,7 @@ class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
|
class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||||
queryset = PowerPort.objects.select_related(
|
queryset = PowerPort.objects.prefetch_related(
|
||||||
'device', 'connected_endpoint__device'
|
'device', 'connected_endpoint__device'
|
||||||
).filter(
|
).filter(
|
||||||
_connected_poweroutlet__isnull=False
|
_connected_poweroutlet__isnull=False
|
||||||
@ -547,7 +517,7 @@ class PowerConnectionViewSet(ListModelMixin, GenericViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class InterfaceConnectionViewSet(ListModelMixin, GenericViewSet):
|
class InterfaceConnectionViewSet(ListModelMixin, GenericViewSet):
|
||||||
queryset = Interface.objects.select_related(
|
queryset = Interface.objects.prefetch_related(
|
||||||
'device', '_connected_interface__device'
|
'device', '_connected_interface__device'
|
||||||
).filter(
|
).filter(
|
||||||
# Avoid duplicate connections by only selecting the lower PK in a connected pair
|
# Avoid duplicate connections by only selecting the lower PK in a connected pair
|
||||||
@ -587,7 +557,7 @@ class VirtualChassisViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class PowerPanelViewSet(ModelViewSet):
|
class PowerPanelViewSet(ModelViewSet):
|
||||||
queryset = PowerPanel.objects.select_related(
|
queryset = PowerPanel.objects.prefetch_related(
|
||||||
'site', 'rack_group'
|
'site', 'rack_group'
|
||||||
).annotate(
|
).annotate(
|
||||||
powerfeed_count=Count('powerfeeds')
|
powerfeed_count=Count('powerfeeds')
|
||||||
@ -601,11 +571,7 @@ class PowerPanelViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class PowerFeedViewSet(CustomFieldModelViewSet):
|
class PowerFeedViewSet(CustomFieldModelViewSet):
|
||||||
queryset = PowerFeed.objects.select_related(
|
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack', 'tags')
|
||||||
'power_panel', 'rack'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.PowerFeedSerializer
|
serializer_class = serializers.PowerFeedSerializer
|
||||||
filterset_class = filters.PowerFeedFilter
|
filterset_class = filters.PowerFeedFilter
|
||||||
|
|
||||||
|
@ -632,7 +632,7 @@ class RackFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm):
|
|||||||
)
|
)
|
||||||
group_id = ChainedModelChoiceField(
|
group_id = ChainedModelChoiceField(
|
||||||
label='Rack group',
|
label='Rack group',
|
||||||
queryset=RackGroup.objects.select_related('site'),
|
queryset=RackGroup.objects.prefetch_related('site'),
|
||||||
chains=(
|
chains=(
|
||||||
('site', 'site'),
|
('site', 'site'),
|
||||||
),
|
),
|
||||||
@ -745,7 +745,7 @@ class RackReservationFilterForm(BootstrapMixin, TenancyFilterForm):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
group_id = FilterChoiceField(
|
group_id = FilterChoiceField(
|
||||||
queryset=RackGroup.objects.select_related('site'),
|
queryset=RackGroup.objects.prefetch_related('site'),
|
||||||
label='Rack group',
|
label='Rack group',
|
||||||
null_label='-- None --',
|
null_label='-- None --',
|
||||||
widget=APISelectMultiple(
|
widget=APISelectMultiple(
|
||||||
@ -1391,14 +1391,14 @@ class DeviceForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
interface_ids = self.instance.vc_interfaces.values('pk')
|
interface_ids = self.instance.vc_interfaces.values('pk')
|
||||||
|
|
||||||
# Collect interface IPs
|
# 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
|
family=family, interface_id__in=interface_ids
|
||||||
)
|
)
|
||||||
if interface_ips:
|
if interface_ips:
|
||||||
ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips]
|
ip_list = [(ip.id, '{} ({})'.format(ip.address, ip.interface)) for ip in interface_ips]
|
||||||
ip_choices.append(('Interface IPs', ip_list))
|
ip_choices.append(('Interface IPs', ip_list))
|
||||||
# Collect NAT IPs
|
# 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
|
family=family, nat_inside__interface__in=interface_ids
|
||||||
)
|
)
|
||||||
if nat_ips:
|
if nat_ips:
|
||||||
@ -1710,7 +1710,7 @@ class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
rack_group_id = FilterChoiceField(
|
rack_group_id = FilterChoiceField(
|
||||||
queryset=RackGroup.objects.select_related(
|
queryset=RackGroup.objects.prefetch_related(
|
||||||
'site'
|
'site'
|
||||||
),
|
),
|
||||||
label='Rack group',
|
label='Rack group',
|
||||||
@ -1749,7 +1749,7 @@ class DeviceFilterForm(BootstrapMixin, TenancyFilterForm, CustomFieldFilterForm)
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
device_type_id = FilterChoiceField(
|
device_type_id = FilterChoiceField(
|
||||||
queryset=DeviceType.objects.select_related(
|
queryset=DeviceType.objects.prefetch_related(
|
||||||
'manufacturer'
|
'manufacturer'
|
||||||
),
|
),
|
||||||
label='Model',
|
label='Model',
|
||||||
|
@ -607,7 +607,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
|||||||
|
|
||||||
# Update racked devices if the assigned Site has been changed.
|
# Update racked devices if the assigned Site has been changed.
|
||||||
if _site_id is not None and self.site_id != _site_id:
|
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):
|
def to_csv(self):
|
||||||
return (
|
return (
|
||||||
@ -664,7 +664,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
|||||||
|
|
||||||
# Add devices to rack units list
|
# Add devices to rack units list
|
||||||
if self.pk:
|
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'))\
|
.annotate(devicebay_count=Count('device_bays'))\
|
||||||
.exclude(pk=exclude)\
|
.exclude(pk=exclude)\
|
||||||
.filter(rack=self, position__gt=0)\
|
.filter(rack=self, position__gt=0)\
|
||||||
@ -697,7 +697,7 @@ class Rack(ChangeLoggedModel, CustomFieldModel):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
# Gather all devices which consume U space within the rack
|
# 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
|
# Initialize the rack unit skeleton
|
||||||
units = list(range(1, self.u_height + 1))
|
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
|
# 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):
|
def to_csv(self):
|
||||||
return (
|
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.
|
When a VirtualChassis is created, automatically assign its master device to the VC.
|
||||||
"""
|
"""
|
||||||
if created:
|
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)
|
@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.
|
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)
|
@receiver(post_save, sender=Cable)
|
||||||
|
@ -3430,11 +3430,11 @@ class VirtualChassisTest(APITestCase):
|
|||||||
|
|
||||||
# Create two VirtualChassis with three members each
|
# Create two VirtualChassis with three members each
|
||||||
self.vc1 = VirtualChassis.objects.create(master=self.device1, domain='test-domain-1')
|
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.device2.pk).invalidated_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.device3.pk).invalidated_update(virtual_chassis=self.vc1, vc_position=3)
|
||||||
self.vc2 = VirtualChassis.objects.create(master=self.device4, domain='test-domain-2')
|
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.device5.pk).invalidated_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.device6.pk).invalidated_update(virtual_chassis=self.vc2, vc_position=3)
|
||||||
|
|
||||||
def test_get_virtualchassis(self):
|
def test_get_virtualchassis(self):
|
||||||
|
|
||||||
|
@ -442,11 +442,11 @@ class VirtualChassisTestCase(TestCase):
|
|||||||
|
|
||||||
# Create three VirtualChassis with two members each
|
# Create three VirtualChassis with two members each
|
||||||
vc1 = VirtualChassis.objects.create(master=device1, domain='test-domain-1')
|
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')
|
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')
|
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):
|
def test_virtualchassis_list(self):
|
||||||
|
|
||||||
|
@ -185,7 +185,7 @@ class RegionBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class SiteListView(PermissionRequiredMixin, ObjectListView):
|
class SiteListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_site'
|
permission_required = 'dcim.view_site'
|
||||||
queryset = Site.objects.select_related('region', 'tenant')
|
queryset = Site.objects.prefetch_related('region', 'tenant')
|
||||||
filter = filters.SiteFilter
|
filter = filters.SiteFilter
|
||||||
filter_form = forms.SiteFilterForm
|
filter_form = forms.SiteFilterForm
|
||||||
table = tables.SiteTable
|
table = tables.SiteTable
|
||||||
@ -197,7 +197,7 @@ class SiteView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, slug):
|
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 = {
|
stats = {
|
||||||
'rack_count': Rack.objects.filter(site=site).count(),
|
'rack_count': Rack.objects.filter(site=site).count(),
|
||||||
'device_count': Device.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):
|
class SiteBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_site'
|
permission_required = 'dcim.change_site'
|
||||||
queryset = Site.objects.select_related('region', 'tenant')
|
queryset = Site.objects.prefetch_related('region', 'tenant')
|
||||||
filter = filters.SiteFilter
|
filter = filters.SiteFilter
|
||||||
table = tables.SiteTable
|
table = tables.SiteTable
|
||||||
form = forms.SiteBulkEditForm
|
form = forms.SiteBulkEditForm
|
||||||
@ -255,7 +255,7 @@ class SiteBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_site'
|
permission_required = 'dcim.delete_site'
|
||||||
queryset = Site.objects.select_related('region', 'tenant')
|
queryset = Site.objects.prefetch_related('region', 'tenant')
|
||||||
filter = filters.SiteFilter
|
filter = filters.SiteFilter
|
||||||
table = tables.SiteTable
|
table = tables.SiteTable
|
||||||
default_return_url = 'dcim:site_list'
|
default_return_url = 'dcim:site_list'
|
||||||
@ -267,7 +267,7 @@ class SiteBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class RackGroupListView(PermissionRequiredMixin, ObjectListView):
|
class RackGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_rackgroup'
|
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 = filters.RackGroupFilter
|
||||||
filter_form = forms.RackGroupFilterForm
|
filter_form = forms.RackGroupFilterForm
|
||||||
table = tables.RackGroupTable
|
table = tables.RackGroupTable
|
||||||
@ -294,7 +294,7 @@ class RackGroupBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class RackGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_rackgroup'
|
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
|
filter = filters.RackGroupFilter
|
||||||
table = tables.RackGroupTable
|
table = tables.RackGroupTable
|
||||||
default_return_url = 'dcim:rackgroup_list'
|
default_return_url = 'dcim:rackgroup_list'
|
||||||
@ -342,10 +342,8 @@ class RackRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class RackListView(PermissionRequiredMixin, ObjectListView):
|
class RackListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_rack'
|
permission_required = 'dcim.view_rack'
|
||||||
queryset = Rack.objects.select_related(
|
queryset = Rack.objects.prefetch_related(
|
||||||
'site', 'group', 'tenant', 'role'
|
'site', 'group', 'tenant', 'role', 'devices__device_type'
|
||||||
).prefetch_related(
|
|
||||||
'devices__device_type'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=Count('devices')
|
device_count=Count('devices')
|
||||||
)
|
)
|
||||||
@ -363,11 +361,7 @@ class RackElevationListView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
|
|
||||||
racks = Rack.objects.select_related(
|
racks = Rack.objects.prefetch_related('site', 'group', 'tenant', 'role', 'devices__device_type')
|
||||||
'site', 'group', 'tenant', 'role'
|
|
||||||
).prefetch_related(
|
|
||||||
'devices__device_type'
|
|
||||||
)
|
|
||||||
racks = filters.RackFilter(request.GET, racks).qs
|
racks = filters.RackFilter(request.GET, racks).qs
|
||||||
total_count = racks.count()
|
total_count = racks.count()
|
||||||
|
|
||||||
@ -402,15 +396,18 @@ class RackView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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) \
|
nonracked_devices = Device.objects.filter(
|
||||||
.select_related('device_type__manufacturer')
|
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()
|
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()
|
prev_rack = Rack.objects.filter(site=rack.site, name__lt=rack.name).order_by('-name').first()
|
||||||
|
|
||||||
reservations = RackReservation.objects.filter(rack=rack)
|
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', {
|
return render(request, 'dcim/rack.html', {
|
||||||
'rack': rack,
|
'rack': rack,
|
||||||
@ -451,7 +448,7 @@ class RackBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_rack'
|
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
|
filter = filters.RackFilter
|
||||||
table = tables.RackTable
|
table = tables.RackTable
|
||||||
form = forms.RackBulkEditForm
|
form = forms.RackBulkEditForm
|
||||||
@ -460,7 +457,7 @@ class RackBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_rack'
|
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
|
filter = filters.RackFilter
|
||||||
table = tables.RackTable
|
table = tables.RackTable
|
||||||
default_return_url = 'dcim:rack_list'
|
default_return_url = 'dcim:rack_list'
|
||||||
@ -472,7 +469,7 @@ class RackBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class RackReservationListView(PermissionRequiredMixin, ObjectListView):
|
class RackReservationListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_rackreservation'
|
permission_required = 'dcim.view_rackreservation'
|
||||||
queryset = RackReservation.objects.select_related('rack__site')
|
queryset = RackReservation.objects.prefetch_related('rack__site')
|
||||||
filter = filters.RackReservationFilter
|
filter = filters.RackReservationFilter
|
||||||
filter_form = forms.RackReservationFilterForm
|
filter_form = forms.RackReservationFilterForm
|
||||||
table = tables.RackReservationTable
|
table = tables.RackReservationTable
|
||||||
@ -508,7 +505,7 @@ class RackReservationDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
|||||||
|
|
||||||
class RackReservationBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class RackReservationBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_rackreservation'
|
permission_required = 'dcim.change_rackreservation'
|
||||||
queryset = RackReservation.objects.select_related('rack', 'user')
|
queryset = RackReservation.objects.prefetch_related('rack', 'user')
|
||||||
filter = filters.RackReservationFilter
|
filter = filters.RackReservationFilter
|
||||||
table = tables.RackReservationTable
|
table = tables.RackReservationTable
|
||||||
form = forms.RackReservationBulkEditForm
|
form = forms.RackReservationBulkEditForm
|
||||||
@ -517,7 +514,7 @@ class RackReservationBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class RackReservationBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class RackReservationBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_rackreservation'
|
permission_required = 'dcim.delete_rackreservation'
|
||||||
queryset = RackReservation.objects.select_related('rack', 'user')
|
queryset = RackReservation.objects.prefetch_related('rack', 'user')
|
||||||
filter = filters.RackReservationFilter
|
filter = filters.RackReservationFilter
|
||||||
table = tables.RackReservationTable
|
table = tables.RackReservationTable
|
||||||
default_return_url = 'dcim:rackreservation_list'
|
default_return_url = 'dcim:rackreservation_list'
|
||||||
@ -569,7 +566,7 @@ class ManufacturerBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class DeviceTypeListView(PermissionRequiredMixin, ObjectListView):
|
class DeviceTypeListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_devicetype'
|
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 = filters.DeviceTypeFilter
|
||||||
filter_form = forms.DeviceTypeFilterForm
|
filter_form = forms.DeviceTypeFilterForm
|
||||||
table = tables.DeviceTypeTable
|
table = tables.DeviceTypeTable
|
||||||
@ -666,7 +663,7 @@ class DeviceTypeBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_devicetype'
|
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
|
filter = filters.DeviceTypeFilter
|
||||||
table = tables.DeviceTypeTable
|
table = tables.DeviceTypeTable
|
||||||
form = forms.DeviceTypeBulkEditForm
|
form = forms.DeviceTypeBulkEditForm
|
||||||
@ -675,7 +672,7 @@ class DeviceTypeBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class DeviceTypeBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_devicetype'
|
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
|
filter = filters.DeviceTypeFilter
|
||||||
table = tables.DeviceTypeTable
|
table = tables.DeviceTypeTable
|
||||||
default_return_url = 'dcim:devicetype_list'
|
default_return_url = 'dcim:devicetype_list'
|
||||||
@ -907,7 +904,7 @@ class PlatformBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class DeviceListView(PermissionRequiredMixin, ObjectListView):
|
class DeviceListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_device'
|
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'
|
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6'
|
||||||
)
|
)
|
||||||
filter = filters.DeviceFilter
|
filter = filters.DeviceFilter
|
||||||
@ -921,7 +918,7 @@ class DeviceView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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'
|
'site__region', 'rack__group', 'tenant__group', 'device_role', 'platform'
|
||||||
), pk=pk)
|
), pk=pk)
|
||||||
|
|
||||||
@ -934,32 +931,31 @@ class DeviceView(PermissionRequiredMixin, View):
|
|||||||
vc_members = []
|
vc_members = []
|
||||||
|
|
||||||
# Console ports
|
# 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
|
# 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
|
||||||
power_ports = device.powerports.select_related('_connected_poweroutlet__device', 'cable')
|
power_ports = device.powerports.prefetch_related('_connected_poweroutlet__device', 'cable')
|
||||||
|
|
||||||
# Power outlets
|
# 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
|
||||||
interfaces = device.vc_interfaces.select_related(
|
interfaces = device.vc_interfaces.prefetch_related(
|
||||||
'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable'
|
'lag', '_connected_interface__device', '_connected_circuittermination__circuit', 'cable',
|
||||||
).prefetch_related(
|
|
||||||
'cable__termination_a', 'cable__termination_b', 'ip_addresses', 'tags'
|
'cable__termination_a', 'cable__termination_b', 'ip_addresses', 'tags'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Front ports
|
# Front ports
|
||||||
front_ports = device.frontports.select_related('rear_port', 'cable')
|
front_ports = device.frontports.prefetch_related('rear_port', 'cable')
|
||||||
|
|
||||||
# Rear ports
|
# Rear ports
|
||||||
rear_ports = device.rearports.select_related('cable')
|
rear_ports = device.rearports.prefetch_related('cable')
|
||||||
|
|
||||||
# Device bays
|
# 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
|
||||||
services = device.services.all()
|
services = device.services.all()
|
||||||
@ -972,7 +968,7 @@ class DeviceView(PermissionRequiredMixin, View):
|
|||||||
site=device.site, device_role=device.device_role
|
site=device.site, device_role=device.device_role
|
||||||
).exclude(
|
).exclude(
|
||||||
pk=device.pk
|
pk=device.pk
|
||||||
).select_related(
|
).prefetch_related(
|
||||||
'rack', 'device_type__manufacturer'
|
'rack', 'device_type__manufacturer'
|
||||||
)[:10]
|
)[:10]
|
||||||
|
|
||||||
@ -1005,10 +1001,8 @@ class DeviceInventoryView(PermissionRequiredMixin, View):
|
|||||||
device = get_object_or_404(Device, pk=pk)
|
device = get_object_or_404(Device, pk=pk)
|
||||||
inventory_items = InventoryItem.objects.filter(
|
inventory_items = InventoryItem.objects.filter(
|
||||||
device=device, parent=None
|
device=device, parent=None
|
||||||
).select_related(
|
|
||||||
'manufacturer'
|
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'child_items'
|
'manufacturer', 'child_items'
|
||||||
)
|
)
|
||||||
|
|
||||||
return render(request, 'dcim/device_inventory.html', {
|
return render(request, 'dcim/device_inventory.html', {
|
||||||
@ -1037,7 +1031,7 @@ class DeviceLLDPNeighborsView(PermissionRequiredMixin, View):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
device = get_object_or_404(Device, pk=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'
|
'_connected_interface__device'
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1114,7 +1108,7 @@ class ChildDeviceBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_device'
|
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
|
filter = filters.DeviceFilter
|
||||||
table = tables.DeviceTable
|
table = tables.DeviceTable
|
||||||
form = forms.DeviceBulkEditForm
|
form = forms.DeviceBulkEditForm
|
||||||
@ -1123,7 +1117,7 @@ class DeviceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class DeviceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_device'
|
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
|
filter = filters.DeviceFilter
|
||||||
table = tables.DeviceTable
|
table = tables.DeviceTable
|
||||||
default_return_url = 'dcim:device_list'
|
default_return_url = 'dcim:device_list'
|
||||||
@ -1310,7 +1304,7 @@ class InterfaceView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
# Get assigned IP addresses
|
# Get assigned IP addresses
|
||||||
ipaddress_table = InterfaceIPAddressTable(
|
ipaddress_table = InterfaceIPAddressTable(
|
||||||
data=interface.ip_addresses.select_related('vrf', 'tenant'),
|
data=interface.ip_addresses.prefetch_related('vrf', 'tenant'),
|
||||||
orderable=False
|
orderable=False
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1319,7 +1313,7 @@ class InterfaceView(PermissionRequiredMixin, View):
|
|||||||
if interface.untagged_vlan is not None:
|
if interface.untagged_vlan is not None:
|
||||||
vlans.append(interface.untagged_vlan)
|
vlans.append(interface.untagged_vlan)
|
||||||
vlans[0].tagged = False
|
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
|
vlan.tagged = True
|
||||||
vlans.append(vlan)
|
vlans.append(vlan)
|
||||||
vlan_table = InterfaceVLANTable(
|
vlan_table = InterfaceVLANTable(
|
||||||
@ -1842,7 +1836,7 @@ class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport')
|
permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport')
|
||||||
queryset = ConsolePort.objects.select_related(
|
queryset = ConsolePort.objects.prefetch_related(
|
||||||
'device', 'connected_endpoint__device'
|
'device', 'connected_endpoint__device'
|
||||||
).filter(
|
).filter(
|
||||||
connected_endpoint__isnull=False
|
connected_endpoint__isnull=False
|
||||||
@ -1873,7 +1867,7 @@ class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
|
|
||||||
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet')
|
permission_required = ('dcim.view_powerport', 'dcim.view_poweroutlet')
|
||||||
queryset = PowerPort.objects.select_related(
|
queryset = PowerPort.objects.prefetch_related(
|
||||||
'device', '_connected_poweroutlet__device'
|
'device', '_connected_poweroutlet__device'
|
||||||
).filter(
|
).filter(
|
||||||
_connected_poweroutlet__isnull=False
|
_connected_poweroutlet__isnull=False
|
||||||
@ -1904,7 +1898,7 @@ class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
|||||||
|
|
||||||
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_interface'
|
permission_required = 'dcim.view_interface'
|
||||||
queryset = Interface.objects.select_related(
|
queryset = Interface.objects.prefetch_related(
|
||||||
'device', 'cable', '_connected_interface__device'
|
'device', 'cable', '_connected_interface__device'
|
||||||
).filter(
|
).filter(
|
||||||
# Avoid duplicate connections by only selecting the lower PK in a connected pair
|
# 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):
|
class InventoryItemListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_inventoryitem'
|
permission_required = 'dcim.view_inventoryitem'
|
||||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
|
||||||
filter = filters.InventoryItemFilter
|
filter = filters.InventoryItemFilter
|
||||||
filter_form = forms.InventoryItemFilterForm
|
filter_form = forms.InventoryItemFilterForm
|
||||||
table = tables.InventoryItemTable
|
table = tables.InventoryItemTable
|
||||||
@ -1982,7 +1976,7 @@ class InventoryItemBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class InventoryItemBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class InventoryItemBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_inventoryitem'
|
permission_required = 'dcim.change_inventoryitem'
|
||||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
|
||||||
filter = filters.InventoryItemFilter
|
filter = filters.InventoryItemFilter
|
||||||
table = tables.InventoryItemTable
|
table = tables.InventoryItemTable
|
||||||
form = forms.InventoryItemBulkEditForm
|
form = forms.InventoryItemBulkEditForm
|
||||||
@ -1991,7 +1985,7 @@ class InventoryItemBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_inventoryitem'
|
permission_required = 'dcim.delete_inventoryitem'
|
||||||
queryset = InventoryItem.objects.select_related('device', 'manufacturer')
|
queryset = InventoryItem.objects.prefetch_related('device', 'manufacturer')
|
||||||
table = tables.InventoryItemTable
|
table = tables.InventoryItemTable
|
||||||
template_name = 'dcim/inventoryitem_bulk_delete.html'
|
template_name = 'dcim/inventoryitem_bulk_delete.html'
|
||||||
default_return_url = 'dcim:inventoryitem_list'
|
default_return_url = 'dcim:inventoryitem_list'
|
||||||
@ -2003,7 +1997,7 @@ class InventoryItemBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class VirtualChassisListView(PermissionRequiredMixin, ObjectListView):
|
class VirtualChassisListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_virtualchassis'
|
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
|
table = tables.VirtualChassisTable
|
||||||
filter = filters.VirtualChassisFilter
|
filter = filters.VirtualChassisFilter
|
||||||
filter_form = forms.VirtualChassisFilterForm
|
filter_form = forms.VirtualChassisFilterForm
|
||||||
@ -2023,7 +2017,7 @@ class VirtualChassisCreateView(PermissionRequiredMixin, View):
|
|||||||
return redirect('dcim:device_list')
|
return redirect('dcim:device_list')
|
||||||
device_queryset = Device.objects.filter(
|
device_queryset = Device.objects.filter(
|
||||||
pk__in=pk_form.cleaned_data.get('pk')
|
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(
|
VCMemberFormSet = modelformset_factory(
|
||||||
model=Device,
|
model=Device,
|
||||||
@ -2077,7 +2071,7 @@ class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
|||||||
formset=forms.BaseVCMemberFormSet,
|
formset=forms.BaseVCMemberFormSet,
|
||||||
extra=0
|
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 = forms.VirtualChassisForm(instance=virtual_chassis)
|
||||||
vc_form.fields['master'].queryset = members_queryset
|
vc_form.fields['master'].queryset = members_queryset
|
||||||
@ -2098,7 +2092,7 @@ class VirtualChassisEditView(PermissionRequiredMixin, GetReturnURLMixin, View):
|
|||||||
formset=forms.BaseVCMemberFormSet,
|
formset=forms.BaseVCMemberFormSet,
|
||||||
extra=0
|
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 = forms.VirtualChassisForm(request.POST, instance=virtual_chassis)
|
||||||
vc_form.fields['master'].queryset = members_queryset
|
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
|
# Nullify the vc_position of each member first to allow reordering without raising an IntegrityError on
|
||||||
# duplicate positions. Then save each member instance.
|
# duplicate positions. Then save each member instance.
|
||||||
members = formset.save(commit=False)
|
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:
|
for member in members:
|
||||||
member.save()
|
member.save()
|
||||||
|
|
||||||
@ -2215,12 +2209,13 @@ class VirtualChassisRemoveMemberView(PermissionRequiredMixin, GetReturnURLMixin,
|
|||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
|
||||||
Device.objects.filter(pk=device.pk).update(
|
Device.objects.filter(pk=device.pk).invalidated_update(
|
||||||
virtual_chassis=None,
|
virtual_chassis=None,
|
||||||
vc_position=None,
|
vc_position=None,
|
||||||
vc_priority=None
|
vc_priority=None
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
msg = 'Removed {} from virtual chassis {}'.format(device, device.virtual_chassis)
|
msg = 'Removed {} from virtual chassis {}'.format(device, device.virtual_chassis)
|
||||||
messages.success(request, msg)
|
messages.success(request, msg)
|
||||||
|
|
||||||
@ -2239,7 +2234,7 @@ class VirtualChassisRemoveMemberView(PermissionRequiredMixin, GetReturnURLMixin,
|
|||||||
|
|
||||||
class PowerPanelListView(PermissionRequiredMixin, ObjectListView):
|
class PowerPanelListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_powerpanel'
|
permission_required = 'dcim.view_powerpanel'
|
||||||
queryset = PowerPanel.objects.select_related(
|
queryset = PowerPanel.objects.prefetch_related(
|
||||||
'site', 'rack_group'
|
'site', 'rack_group'
|
||||||
).annotate(
|
).annotate(
|
||||||
powerfeed_count=Count('powerfeeds')
|
powerfeed_count=Count('powerfeeds')
|
||||||
@ -2255,9 +2250,9 @@ class PowerPanelView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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(
|
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
|
orderable=False
|
||||||
)
|
)
|
||||||
powerfeed_table.exclude = ['power_panel']
|
powerfeed_table.exclude = ['power_panel']
|
||||||
@ -2294,7 +2289,7 @@ class PowerPanelBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_powerpanel'
|
permission_required = 'dcim.delete_powerpanel'
|
||||||
queryset = PowerPanel.objects.select_related(
|
queryset = PowerPanel.objects.prefetch_related(
|
||||||
'site', 'rack_group'
|
'site', 'rack_group'
|
||||||
).annotate(
|
).annotate(
|
||||||
rack_count=Count('powerfeeds')
|
rack_count=Count('powerfeeds')
|
||||||
@ -2310,7 +2305,7 @@ class PowerPanelBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class PowerFeedListView(PermissionRequiredMixin, ObjectListView):
|
class PowerFeedListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'dcim.view_powerfeed'
|
permission_required = 'dcim.view_powerfeed'
|
||||||
queryset = PowerFeed.objects.select_related(
|
queryset = PowerFeed.objects.prefetch_related(
|
||||||
'power_panel', 'rack'
|
'power_panel', 'rack'
|
||||||
)
|
)
|
||||||
filter = filters.PowerFeedFilter
|
filter = filters.PowerFeedFilter
|
||||||
@ -2324,7 +2319,7 @@ class PowerFeedView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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', {
|
return render(request, 'dcim/powerfeed.html', {
|
||||||
'powerfeed': powerfeed,
|
'powerfeed': powerfeed,
|
||||||
@ -2358,7 +2353,7 @@ class PowerFeedBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'dcim.change_powerfeed'
|
permission_required = 'dcim.change_powerfeed'
|
||||||
queryset = PowerFeed.objects.select_related('power_panel', 'rack')
|
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
|
||||||
filter = filters.PowerFeedFilter
|
filter = filters.PowerFeedFilter
|
||||||
table = tables.PowerFeedTable
|
table = tables.PowerFeedTable
|
||||||
form = forms.PowerFeedBulkEditForm
|
form = forms.PowerFeedBulkEditForm
|
||||||
@ -2367,7 +2362,7 @@ class PowerFeedBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class PowerFeedBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class PowerFeedBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'dcim.delete_powerfeed'
|
permission_required = 'dcim.delete_powerfeed'
|
||||||
queryset = PowerFeed.objects.select_related('power_panel', 'rack')
|
queryset = PowerFeed.objects.prefetch_related('power_panel', 'rack')
|
||||||
filter = filters.PowerFeedFilter
|
filter = filters.PowerFeedFilter
|
||||||
table = tables.PowerFeedTable
|
table = tables.PowerFeedTable
|
||||||
default_return_url = 'dcim:powerfeed_list'
|
default_return_url = 'dcim:powerfeed_list'
|
||||||
|
@ -120,7 +120,7 @@ class ExportTemplateViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class TopologyMapViewSet(ModelViewSet):
|
class TopologyMapViewSet(ModelViewSet):
|
||||||
queryset = TopologyMap.objects.select_related('site')
|
queryset = TopologyMap.objects.prefetch_related('site')
|
||||||
serializer_class = serializers.TopologyMapSerializer
|
serializer_class = serializers.TopologyMapSerializer
|
||||||
filterset_class = filters.TopologyMapFilter
|
filterset_class = filters.TopologyMapFilter
|
||||||
|
|
||||||
@ -260,6 +260,6 @@ class ObjectChangeViewSet(ReadOnlyModelViewSet):
|
|||||||
"""
|
"""
|
||||||
Retrieve a list of recent changes.
|
Retrieve a list of recent changes.
|
||||||
"""
|
"""
|
||||||
queryset = ObjectChange.objects.select_related('user')
|
queryset = ObjectChange.objects.prefetch_related('user')
|
||||||
serializer_class = serializers.ObjectChangeSerializer
|
serializer_class = serializers.ObjectChangeSerializer
|
||||||
filterset_class = filters.ObjectChangeFilter
|
filterset_class = filters.ObjectChangeFilter
|
||||||
|
@ -111,8 +111,10 @@ class CustomFieldForm(forms.ModelForm):
|
|||||||
|
|
||||||
# If editing an existing object, initialize values for all custom fields
|
# If editing an existing object, initialize values for all custom fields
|
||||||
if self.instance.pk:
|
if self.instance.pk:
|
||||||
existing_values = CustomFieldValue.objects.filter(obj_type=self.obj_type, obj_id=self.instance.pk)\
|
existing_values = CustomFieldValue.objects.filter(
|
||||||
.select_related('field')
|
obj_type=self.obj_type,
|
||||||
|
obj_id=self.instance.pk
|
||||||
|
).prefetch_related('field')
|
||||||
for cfv in existing_values:
|
for cfv in existing_values:
|
||||||
self.initial['cf_{}'.format(str(cfv.field.name))] = cfv.serialized_value
|
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:
|
for field_name in self.custom_fields:
|
||||||
try:
|
try:
|
||||||
cfv = CustomFieldValue.objects.select_related('field').get(field=self.fields[field_name].model,
|
cfv = CustomFieldValue.objects.prefetch_related('field').get(
|
||||||
obj_type=self.obj_type,
|
field=self.fields[field_name].model,
|
||||||
obj_id=self.instance.pk)
|
obj_type=self.obj_type,
|
||||||
|
obj_id=self.instance.pk
|
||||||
|
)
|
||||||
except CustomFieldValue.DoesNotExist:
|
except CustomFieldValue.DoesNotExist:
|
||||||
# Skip this field if none exists already and its value is empty
|
# Skip this field if none exists already and its value is empty
|
||||||
if self.cleaned_data[field_name] in [None, '']:
|
if self.cleaned_data[field_name] in [None, '']:
|
||||||
|
@ -569,7 +569,7 @@ class TopologyMap(models.Model):
|
|||||||
# Add each device to the graph
|
# Add each device to the graph
|
||||||
devices = []
|
devices = []
|
||||||
for query in device_set.strip(';').split(';'): # Split regexes on semicolons
|
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
|
# Remove duplicate devices
|
||||||
devices = [d for d in devices if d.id not in seen]
|
devices = [d for d in devices if d.id not in seen]
|
||||||
seen.update([d.id for d in devices])
|
seen.update([d.id for d in devices])
|
||||||
@ -607,7 +607,7 @@ class TopologyMap(models.Model):
|
|||||||
from dcim.models import Interface
|
from dcim.models import Interface
|
||||||
|
|
||||||
# Add all interface connections to the graph
|
# Add all interface connections to the graph
|
||||||
connected_interfaces = Interface.objects.select_related(
|
connected_interfaces = Interface.objects.prefetch_related(
|
||||||
'_connected_interface__device'
|
'_connected_interface__device'
|
||||||
).filter(
|
).filter(
|
||||||
Q(device__in=devices) | Q(_connected_interface__device__in=devices),
|
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)
|
tag = get_object_or_404(Tag, slug=slug)
|
||||||
tagged_items = TaggedItem.objects.filter(
|
tagged_items = TaggedItem.objects.filter(
|
||||||
tag=tag
|
tag=tag
|
||||||
).select_related(
|
|
||||||
'content_type'
|
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'content_object'
|
'content_type', 'content_object'
|
||||||
)
|
)
|
||||||
|
|
||||||
# Generate a table of all items tagged with this Tag
|
# Generate a table of all items tagged with this Tag
|
||||||
@ -178,7 +176,7 @@ class ObjectConfigContextView(View):
|
|||||||
|
|
||||||
class ObjectChangeListView(PermissionRequiredMixin, ObjectListView):
|
class ObjectChangeListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'extras.view_objectchange'
|
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 = filters.ObjectChangeFilter
|
||||||
filter_form = ObjectChangeFilterForm
|
filter_form = ObjectChangeFilterForm
|
||||||
table = ObjectChangeTable
|
table = ObjectChangeTable
|
||||||
@ -217,7 +215,7 @@ class ObjectChangeLogView(View):
|
|||||||
|
|
||||||
# Gather all changes for this object (and its related objects)
|
# Gather all changes for this object (and its related objects)
|
||||||
content_type = ContentType.objects.get_for_model(model)
|
content_type = ContentType.objects.get_for_model(model)
|
||||||
objectchanges = ObjectChange.objects.select_related(
|
objectchanges = ObjectChange.objects.prefetch_related(
|
||||||
'user', 'changed_object_type'
|
'user', 'changed_object_type'
|
||||||
).filter(
|
).filter(
|
||||||
Q(changed_object_type=content_type, changed_object_id=obj.pk) |
|
Q(changed_object_type=content_type, changed_object_id=obj.pk) |
|
||||||
|
@ -33,7 +33,7 @@ class IPAMFieldChoicesViewSet(FieldChoicesViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class VRFViewSet(CustomFieldModelViewSet):
|
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'),
|
ipaddress_count=get_subquery(IPAddress, 'vrf'),
|
||||||
prefix_count=get_subquery(Prefix, 'vrf')
|
prefix_count=get_subquery(Prefix, 'vrf')
|
||||||
)
|
)
|
||||||
@ -58,7 +58,7 @@ class RIRViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class AggregateViewSet(CustomFieldModelViewSet):
|
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
|
serializer_class = serializers.AggregateSerializer
|
||||||
filterset_class = filters.AggregateFilter
|
filterset_class = filters.AggregateFilter
|
||||||
|
|
||||||
@ -81,11 +81,7 @@ class RoleViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class PrefixViewSet(CustomFieldModelViewSet):
|
class PrefixViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Prefix.objects.select_related(
|
queryset = Prefix.objects.prefetch_related('site', 'vrf__tenant', 'tenant', 'vlan', 'role', 'tags')
|
||||||
'site', 'vrf__tenant', 'tenant', 'vlan', 'role'
|
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
)
|
|
||||||
serializer_class = serializers.PrefixSerializer
|
serializer_class = serializers.PrefixSerializer
|
||||||
filterset_class = filters.PrefixFilter
|
filterset_class = filters.PrefixFilter
|
||||||
|
|
||||||
@ -263,9 +259,8 @@ class PrefixViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class IPAddressViewSet(CustomFieldModelViewSet):
|
class IPAddressViewSet(CustomFieldModelViewSet):
|
||||||
queryset = IPAddress.objects.select_related(
|
queryset = IPAddress.objects.prefetch_related(
|
||||||
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device__device_type', 'interface__virtual_machine'
|
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device__device_type', 'interface__virtual_machine',
|
||||||
).prefetch_related(
|
|
||||||
'nat_outside', 'tags',
|
'nat_outside', 'tags',
|
||||||
)
|
)
|
||||||
serializer_class = serializers.IPAddressSerializer
|
serializer_class = serializers.IPAddressSerializer
|
||||||
@ -277,7 +272,7 @@ class IPAddressViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class VLANGroupViewSet(ModelViewSet):
|
class VLANGroupViewSet(ModelViewSet):
|
||||||
queryset = VLANGroup.objects.select_related('site').annotate(
|
queryset = VLANGroup.objects.prefetch_related('site').annotate(
|
||||||
vlan_count=Count('vlans')
|
vlan_count=Count('vlans')
|
||||||
)
|
)
|
||||||
serializer_class = serializers.VLANGroupSerializer
|
serializer_class = serializers.VLANGroupSerializer
|
||||||
@ -289,10 +284,8 @@ class VLANGroupViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class VLANViewSet(CustomFieldModelViewSet):
|
class VLANViewSet(CustomFieldModelViewSet):
|
||||||
queryset = VLAN.objects.select_related(
|
queryset = VLAN.objects.prefetch_related(
|
||||||
'site', 'group', 'tenant', 'role'
|
'site', 'group', 'tenant', 'role', 'tags'
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
prefix_count=get_subquery(Prefix, 'role')
|
prefix_count=get_subquery(Prefix, 'role')
|
||||||
)
|
)
|
||||||
@ -305,6 +298,6 @@ class VLANViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class ServiceViewSet(ModelViewSet):
|
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
|
serializer_class = serializers.ServiceSerializer
|
||||||
filterset_class = filters.ServiceFilter
|
filterset_class = filters.ServiceFilter
|
||||||
|
@ -360,7 +360,7 @@ class IPAddressFilter(TenancyFilterSet, CustomFieldFilterSet):
|
|||||||
|
|
||||||
def filter_device(self, queryset, name, value):
|
def filter_device(self, queryset, name, value):
|
||||||
try:
|
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')]
|
vc_interface_ids = [i['id'] for i in device.vc_interfaces.values('id')]
|
||||||
return queryset.filter(interface_id__in=vc_interface_ids)
|
return queryset.filter(interface_id__in=vc_interface_ids)
|
||||||
except Device.DoesNotExist:
|
except Device.DoesNotExist:
|
||||||
|
@ -115,7 +115,7 @@ def add_available_vlans(vlan_group, vlans):
|
|||||||
|
|
||||||
class VRFListView(PermissionRequiredMixin, ObjectListView):
|
class VRFListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_vrf'
|
permission_required = 'ipam.view_vrf'
|
||||||
queryset = VRF.objects.select_related('tenant')
|
queryset = VRF.objects.prefetch_related('tenant')
|
||||||
filter = filters.VRFFilter
|
filter = filters.VRFFilter
|
||||||
filter_form = forms.VRFFilterForm
|
filter_form = forms.VRFFilterForm
|
||||||
table = tables.VRFTable
|
table = tables.VRFTable
|
||||||
@ -163,7 +163,7 @@ class VRFBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class VRFBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class VRFBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'ipam.change_vrf'
|
permission_required = 'ipam.change_vrf'
|
||||||
queryset = VRF.objects.select_related('tenant')
|
queryset = VRF.objects.prefetch_related('tenant')
|
||||||
filter = filters.VRFFilter
|
filter = filters.VRFFilter
|
||||||
table = tables.VRFTable
|
table = tables.VRFTable
|
||||||
form = forms.VRFBulkEditForm
|
form = forms.VRFBulkEditForm
|
||||||
@ -172,7 +172,7 @@ class VRFBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class VRFBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_vrf'
|
permission_required = 'ipam.delete_vrf'
|
||||||
queryset = VRF.objects.select_related('tenant')
|
queryset = VRF.objects.prefetch_related('tenant')
|
||||||
filter = filters.VRFFilter
|
filter = filters.VRFFilter
|
||||||
table = tables.VRFTable
|
table = tables.VRFTable
|
||||||
default_return_url = 'ipam:vrf_list'
|
default_return_url = 'ipam:vrf_list'
|
||||||
@ -291,7 +291,7 @@ class RIRBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class AggregateListView(PermissionRequiredMixin, ObjectListView):
|
class AggregateListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_aggregate'
|
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',
|
'child_count': 'SELECT COUNT(*) FROM ipam_prefix WHERE ipam_prefix.prefix <<= ipam_aggregate.prefix',
|
||||||
})
|
})
|
||||||
filter = filters.AggregateFilter
|
filter = filters.AggregateFilter
|
||||||
@ -326,7 +326,7 @@ class AggregateView(PermissionRequiredMixin, View):
|
|||||||
# Find all child prefixes contained by this aggregate
|
# Find all child prefixes contained by this aggregate
|
||||||
child_prefixes = Prefix.objects.filter(
|
child_prefixes = Prefix.objects.filter(
|
||||||
prefix__net_contained_or_equal=str(aggregate.prefix)
|
prefix__net_contained_or_equal=str(aggregate.prefix)
|
||||||
).select_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
).annotate_depth(
|
).annotate_depth(
|
||||||
limit=0
|
limit=0
|
||||||
@ -384,7 +384,7 @@ class AggregateBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class AggregateBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class AggregateBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'ipam.change_aggregate'
|
permission_required = 'ipam.change_aggregate'
|
||||||
queryset = Aggregate.objects.select_related('rir')
|
queryset = Aggregate.objects.prefetch_related('rir')
|
||||||
filter = filters.AggregateFilter
|
filter = filters.AggregateFilter
|
||||||
table = tables.AggregateTable
|
table = tables.AggregateTable
|
||||||
form = forms.AggregateBulkEditForm
|
form = forms.AggregateBulkEditForm
|
||||||
@ -393,7 +393,7 @@ class AggregateBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class AggregateBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_aggregate'
|
permission_required = 'ipam.delete_aggregate'
|
||||||
queryset = Aggregate.objects.select_related('rir')
|
queryset = Aggregate.objects.prefetch_related('rir')
|
||||||
filter = filters.AggregateFilter
|
filter = filters.AggregateFilter
|
||||||
table = tables.AggregateTable
|
table = tables.AggregateTable
|
||||||
default_return_url = 'ipam:aggregate_list'
|
default_return_url = 'ipam:aggregate_list'
|
||||||
@ -441,7 +441,7 @@ class RoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class PrefixListView(PermissionRequiredMixin, ObjectListView):
|
class PrefixListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_prefix'
|
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 = filters.PrefixFilter
|
||||||
filter_form = forms.PrefixFilterForm
|
filter_form = forms.PrefixFilterForm
|
||||||
table = tables.PrefixDetailTable
|
table = tables.PrefixDetailTable
|
||||||
@ -458,7 +458,7 @@ class PrefixView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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'
|
'vrf', 'site__region', 'tenant__group', 'vlan__group', 'role'
|
||||||
), pk=pk)
|
), pk=pk)
|
||||||
|
|
||||||
@ -472,7 +472,7 @@ class PrefixView(PermissionRequiredMixin, View):
|
|||||||
Q(vrf=prefix.vrf) | Q(vrf__isnull=True)
|
Q(vrf=prefix.vrf) | Q(vrf__isnull=True)
|
||||||
).filter(
|
).filter(
|
||||||
prefix__net_contains=str(prefix.prefix)
|
prefix__net_contains=str(prefix.prefix)
|
||||||
).select_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
).annotate_depth()
|
).annotate_depth()
|
||||||
parent_prefix_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
|
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)
|
vrf=prefix.vrf, prefix=str(prefix.prefix)
|
||||||
).exclude(
|
).exclude(
|
||||||
pk=prefix.pk
|
pk=prefix.pk
|
||||||
).select_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
)
|
)
|
||||||
duplicate_prefix_table = tables.PrefixTable(list(duplicate_prefixes), orderable=False)
|
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)
|
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||||
|
|
||||||
# Child prefixes table
|
# Child prefixes table
|
||||||
child_prefixes = prefix.get_child_prefixes().select_related(
|
child_prefixes = prefix.get_child_prefixes().prefetch_related(
|
||||||
'site', 'vlan', 'role',
|
'site', 'vlan', 'role',
|
||||||
).annotate_depth(limit=0)
|
).annotate_depth(limit=0)
|
||||||
|
|
||||||
@ -548,7 +548,7 @@ class PrefixIPAddressesView(PermissionRequiredMixin, View):
|
|||||||
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
prefix = get_object_or_404(Prefix.objects.all(), pk=pk)
|
||||||
|
|
||||||
# Find all IPAddresses belonging to this Prefix
|
# 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'
|
'vrf', 'interface__device', 'primary_ip4_for', 'primary_ip6_for'
|
||||||
)
|
)
|
||||||
ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)
|
ipaddresses = add_available_ipaddresses(prefix.prefix, ipaddresses, prefix.is_pool)
|
||||||
@ -608,7 +608,7 @@ class PrefixBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'ipam.change_prefix'
|
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
|
filter = filters.PrefixFilter
|
||||||
table = tables.PrefixTable
|
table = tables.PrefixTable
|
||||||
form = forms.PrefixBulkEditForm
|
form = forms.PrefixBulkEditForm
|
||||||
@ -617,7 +617,7 @@ class PrefixBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_prefix'
|
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
|
filter = filters.PrefixFilter
|
||||||
table = tables.PrefixTable
|
table = tables.PrefixTable
|
||||||
default_return_url = 'ipam:prefix_list'
|
default_return_url = 'ipam:prefix_list'
|
||||||
@ -629,10 +629,8 @@ class PrefixBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class IPAddressListView(PermissionRequiredMixin, ObjectListView):
|
class IPAddressListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_ipaddress'
|
permission_required = 'ipam.view_ipaddress'
|
||||||
queryset = IPAddress.objects.select_related(
|
queryset = IPAddress.objects.prefetch_related(
|
||||||
'vrf__tenant', 'tenant', 'nat_inside'
|
'vrf__tenant', 'tenant', 'nat_inside', 'interface__device', 'interface__virtual_machine'
|
||||||
).prefetch_related(
|
|
||||||
'interface__device', 'interface__virtual_machine'
|
|
||||||
)
|
)
|
||||||
filter = filters.IPAddressFilter
|
filter = filters.IPAddressFilter
|
||||||
filter_form = forms.IPAddressFilterForm
|
filter_form = forms.IPAddressFilterForm
|
||||||
@ -645,12 +643,12 @@ class IPAddressView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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 table
|
||||||
parent_prefixes = Prefix.objects.filter(
|
parent_prefixes = Prefix.objects.filter(
|
||||||
vrf=ipaddress.vrf, prefix__net_contains=str(ipaddress.address.ip)
|
vrf=ipaddress.vrf, prefix__net_contains=str(ipaddress.address.ip)
|
||||||
).select_related(
|
).prefetch_related(
|
||||||
'site', 'role'
|
'site', 'role'
|
||||||
)
|
)
|
||||||
parent_prefixes_table = tables.PrefixTable(list(parent_prefixes), orderable=False)
|
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)
|
vrf=ipaddress.vrf, address=str(ipaddress.address)
|
||||||
).exclude(
|
).exclude(
|
||||||
pk=ipaddress.pk
|
pk=ipaddress.pk
|
||||||
).select_related(
|
|
||||||
'nat_inside'
|
|
||||||
).prefetch_related(
|
).prefetch_related(
|
||||||
'interface__device'
|
'nat_inside', 'interface__device'
|
||||||
)
|
)
|
||||||
# Exclude anycast IPs if this IP is anycast
|
# Exclude anycast IPs if this IP is anycast
|
||||||
if ipaddress.role == IPADDRESS_ROLE_ANYCAST:
|
if ipaddress.role == IPADDRESS_ROLE_ANYCAST:
|
||||||
@ -742,7 +738,7 @@ class IPAddressAssignView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
|
|
||||||
queryset = IPAddress.objects.select_related(
|
queryset = IPAddress.objects.prefetch_related(
|
||||||
'vrf', 'tenant', 'interface__device', 'interface__virtual_machine'
|
'vrf', 'tenant', 'interface__device', 'interface__virtual_machine'
|
||||||
).filter(
|
).filter(
|
||||||
vrf=form.cleaned_data['vrf'],
|
vrf=form.cleaned_data['vrf'],
|
||||||
@ -781,7 +777,7 @@ class IPAddressBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'ipam.change_ipaddress'
|
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
|
filter = filters.IPAddressFilter
|
||||||
table = tables.IPAddressTable
|
table = tables.IPAddressTable
|
||||||
form = forms.IPAddressBulkEditForm
|
form = forms.IPAddressBulkEditForm
|
||||||
@ -790,7 +786,7 @@ class IPAddressBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_ipaddress'
|
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
|
filter = filters.IPAddressFilter
|
||||||
table = tables.IPAddressTable
|
table = tables.IPAddressTable
|
||||||
default_return_url = 'ipam:ipaddress_list'
|
default_return_url = 'ipam:ipaddress_list'
|
||||||
@ -802,7 +798,7 @@ class IPAddressBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class VLANGroupListView(PermissionRequiredMixin, ObjectListView):
|
class VLANGroupListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_vlangroup'
|
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 = filters.VLANGroupFilter
|
||||||
filter_form = forms.VLANGroupFilterForm
|
filter_form = forms.VLANGroupFilterForm
|
||||||
table = tables.VLANGroupTable
|
table = tables.VLANGroupTable
|
||||||
@ -829,7 +825,7 @@ class VLANGroupBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class VLANGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class VLANGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_vlangroup'
|
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
|
filter = filters.VLANGroupFilter
|
||||||
table = tables.VLANGroupTable
|
table = tables.VLANGroupTable
|
||||||
default_return_url = 'ipam:vlangroup_list'
|
default_return_url = 'ipam:vlangroup_list'
|
||||||
@ -878,7 +874,7 @@ class VLANGroupVLANsView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
class VLANListView(PermissionRequiredMixin, ObjectListView):
|
class VLANListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_vlan'
|
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 = filters.VLANFilter
|
||||||
filter_form = forms.VLANFilterForm
|
filter_form = forms.VLANFilterForm
|
||||||
table = tables.VLANDetailTable
|
table = tables.VLANDetailTable
|
||||||
@ -890,10 +886,10 @@ class VLANView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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'
|
'site__region', 'tenant__group', 'role'
|
||||||
), pk=pk)
|
), 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 = tables.PrefixTable(list(prefixes), orderable=False)
|
||||||
prefix_table.exclude = ('vlan',)
|
prefix_table.exclude = ('vlan',)
|
||||||
|
|
||||||
@ -909,7 +905,7 @@ class VLANMembersView(PermissionRequiredMixin, View):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
vlan = get_object_or_404(VLAN.objects.all(), pk=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)
|
members_table = tables.VLANMemberTable(members)
|
||||||
|
|
||||||
@ -953,7 +949,7 @@ class VLANBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class VLANBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class VLANBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'ipam.change_vlan'
|
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
|
filter = filters.VLANFilter
|
||||||
table = tables.VLANTable
|
table = tables.VLANTable
|
||||||
form = forms.VLANBulkEditForm
|
form = forms.VLANBulkEditForm
|
||||||
@ -962,7 +958,7 @@ class VLANBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_vlan'
|
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
|
filter = filters.VLANFilter
|
||||||
table = tables.VLANTable
|
table = tables.VLANTable
|
||||||
default_return_url = 'ipam:vlan_list'
|
default_return_url = 'ipam:vlan_list'
|
||||||
@ -974,7 +970,7 @@ class VLANBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class ServiceListView(PermissionRequiredMixin, ObjectListView):
|
class ServiceListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'ipam.view_service'
|
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 = filters.ServiceFilter
|
||||||
filter_form = forms.ServiceFilterForm
|
filter_form = forms.ServiceFilterForm
|
||||||
table = tables.ServiceTable
|
table = tables.ServiceTable
|
||||||
@ -1021,7 +1017,7 @@ class ServiceDeleteView(PermissionRequiredMixin, ObjectDeleteView):
|
|||||||
|
|
||||||
class ServiceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class ServiceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'ipam.change_service'
|
permission_required = 'ipam.change_service'
|
||||||
queryset = Service.objects.select_related('device', 'virtual_machine')
|
queryset = Service.objects.prefetch_related('device', 'virtual_machine')
|
||||||
filter = filters.ServiceFilter
|
filter = filters.ServiceFilter
|
||||||
table = tables.ServiceTable
|
table = tables.ServiceTable
|
||||||
form = forms.ServiceBulkEditForm
|
form = forms.ServiceBulkEditForm
|
||||||
@ -1030,7 +1026,7 @@ class ServiceBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class ServiceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class ServiceBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'ipam.delete_service'
|
permission_required = 'ipam.delete_service'
|
||||||
queryset = Service.objects.select_related('device', 'virtual_machine')
|
queryset = Service.objects.prefetch_related('device', 'virtual_machine')
|
||||||
filter = filters.ServiceFilter
|
filter = filters.ServiceFilter
|
||||||
table = tables.ServiceTable
|
table = tables.ServiceTable
|
||||||
default_return_url = 'ipam:service_list'
|
default_return_url = 'ipam:service_list'
|
||||||
|
@ -37,7 +37,7 @@ class TokenAuthentication(authentication.TokenAuthentication):
|
|||||||
def authenticate_credentials(self, key):
|
def authenticate_credentials(self, key):
|
||||||
model = self.get_model()
|
model = self.get_model()
|
||||||
try:
|
try:
|
||||||
token = model.objects.select_related('user').get(key=key)
|
token = model.objects.prefetch_related('user').get(key=key)
|
||||||
except model.DoesNotExist:
|
except model.DoesNotExist:
|
||||||
raise exceptions.AuthenticationFailed("Invalid token")
|
raise exceptions.AuthenticationFailed("Invalid token")
|
||||||
|
|
||||||
|
@ -46,38 +46,38 @@ SEARCH_TYPES = OrderedDict((
|
|||||||
'url': 'circuits:provider_list',
|
'url': 'circuits:provider_list',
|
||||||
}),
|
}),
|
||||||
('circuit', {
|
('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,
|
'filter': CircuitFilter,
|
||||||
'table': CircuitTable,
|
'table': CircuitTable,
|
||||||
'url': 'circuits:circuit_list',
|
'url': 'circuits:circuit_list',
|
||||||
}),
|
}),
|
||||||
# DCIM
|
# DCIM
|
||||||
('site', {
|
('site', {
|
||||||
'queryset': Site.objects.select_related('region', 'tenant'),
|
'queryset': Site.objects.prefetch_related('region', 'tenant'),
|
||||||
'filter': SiteFilter,
|
'filter': SiteFilter,
|
||||||
'table': SiteTable,
|
'table': SiteTable,
|
||||||
'url': 'dcim:site_list',
|
'url': 'dcim:site_list',
|
||||||
}),
|
}),
|
||||||
('rack', {
|
('rack', {
|
||||||
'queryset': Rack.objects.select_related('site', 'group', 'tenant', 'role'),
|
'queryset': Rack.objects.prefetch_related('site', 'group', 'tenant', 'role'),
|
||||||
'filter': RackFilter,
|
'filter': RackFilter,
|
||||||
'table': RackTable,
|
'table': RackTable,
|
||||||
'url': 'dcim:rack_list',
|
'url': 'dcim:rack_list',
|
||||||
}),
|
}),
|
||||||
('rackgroup', {
|
('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,
|
'filter': RackGroupFilter,
|
||||||
'table': RackGroupTable,
|
'table': RackGroupTable,
|
||||||
'url': 'dcim:rackgroup_list',
|
'url': 'dcim:rackgroup_list',
|
||||||
}),
|
}),
|
||||||
('devicetype', {
|
('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,
|
'filter': DeviceTypeFilter,
|
||||||
'table': DeviceTypeTable,
|
'table': DeviceTypeTable,
|
||||||
'url': 'dcim:devicetype_list',
|
'url': 'dcim:devicetype_list',
|
||||||
}),
|
}),
|
||||||
('device', {
|
('device', {
|
||||||
'queryset': Device.objects.select_related(
|
'queryset': Device.objects.prefetch_related(
|
||||||
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6',
|
'device_type__manufacturer', 'device_role', 'tenant', 'site', 'rack', 'primary_ip4', 'primary_ip6',
|
||||||
),
|
),
|
||||||
'filter': DeviceFilter,
|
'filter': DeviceFilter,
|
||||||
@ -85,7 +85,7 @@ SEARCH_TYPES = OrderedDict((
|
|||||||
'url': 'dcim:device_list',
|
'url': 'dcim:device_list',
|
||||||
}),
|
}),
|
||||||
('virtualchassis', {
|
('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,
|
'filter': VirtualChassisFilter,
|
||||||
'table': VirtualChassisTable,
|
'table': VirtualChassisTable,
|
||||||
'url': 'dcim:virtualchassis_list',
|
'url': 'dcim:virtualchassis_list',
|
||||||
@ -104,58 +104,58 @@ SEARCH_TYPES = OrderedDict((
|
|||||||
}),
|
}),
|
||||||
# IPAM
|
# IPAM
|
||||||
('vrf', {
|
('vrf', {
|
||||||
'queryset': VRF.objects.select_related('tenant'),
|
'queryset': VRF.objects.prefetch_related('tenant'),
|
||||||
'filter': VRFFilter,
|
'filter': VRFFilter,
|
||||||
'table': VRFTable,
|
'table': VRFTable,
|
||||||
'url': 'ipam:vrf_list',
|
'url': 'ipam:vrf_list',
|
||||||
}),
|
}),
|
||||||
('aggregate', {
|
('aggregate', {
|
||||||
'queryset': Aggregate.objects.select_related('rir'),
|
'queryset': Aggregate.objects.prefetch_related('rir'),
|
||||||
'filter': AggregateFilter,
|
'filter': AggregateFilter,
|
||||||
'table': AggregateTable,
|
'table': AggregateTable,
|
||||||
'url': 'ipam:aggregate_list',
|
'url': 'ipam:aggregate_list',
|
||||||
}),
|
}),
|
||||||
('prefix', {
|
('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,
|
'filter': PrefixFilter,
|
||||||
'table': PrefixTable,
|
'table': PrefixTable,
|
||||||
'url': 'ipam:prefix_list',
|
'url': 'ipam:prefix_list',
|
||||||
}),
|
}),
|
||||||
('ipaddress', {
|
('ipaddress', {
|
||||||
'queryset': IPAddress.objects.select_related('vrf__tenant', 'tenant'),
|
'queryset': IPAddress.objects.prefetch_related('vrf__tenant', 'tenant'),
|
||||||
'filter': IPAddressFilter,
|
'filter': IPAddressFilter,
|
||||||
'table': IPAddressTable,
|
'table': IPAddressTable,
|
||||||
'url': 'ipam:ipaddress_list',
|
'url': 'ipam:ipaddress_list',
|
||||||
}),
|
}),
|
||||||
('vlan', {
|
('vlan', {
|
||||||
'queryset': VLAN.objects.select_related('site', 'group', 'tenant', 'role'),
|
'queryset': VLAN.objects.prefetch_related('site', 'group', 'tenant', 'role'),
|
||||||
'filter': VLANFilter,
|
'filter': VLANFilter,
|
||||||
'table': VLANTable,
|
'table': VLANTable,
|
||||||
'url': 'ipam:vlan_list',
|
'url': 'ipam:vlan_list',
|
||||||
}),
|
}),
|
||||||
# Secrets
|
# Secrets
|
||||||
('secret', {
|
('secret', {
|
||||||
'queryset': Secret.objects.select_related('role', 'device'),
|
'queryset': Secret.objects.prefetch_related('role', 'device'),
|
||||||
'filter': SecretFilter,
|
'filter': SecretFilter,
|
||||||
'table': SecretTable,
|
'table': SecretTable,
|
||||||
'url': 'secrets:secret_list',
|
'url': 'secrets:secret_list',
|
||||||
}),
|
}),
|
||||||
# Tenancy
|
# Tenancy
|
||||||
('tenant', {
|
('tenant', {
|
||||||
'queryset': Tenant.objects.select_related('group'),
|
'queryset': Tenant.objects.prefetch_related('group'),
|
||||||
'filter': TenantFilter,
|
'filter': TenantFilter,
|
||||||
'table': TenantTable,
|
'table': TenantTable,
|
||||||
'url': 'tenancy:tenant_list',
|
'url': 'tenancy:tenant_list',
|
||||||
}),
|
}),
|
||||||
# Virtualization
|
# Virtualization
|
||||||
('cluster', {
|
('cluster', {
|
||||||
'queryset': Cluster.objects.select_related('type', 'group'),
|
'queryset': Cluster.objects.prefetch_related('type', 'group'),
|
||||||
'filter': ClusterFilter,
|
'filter': ClusterFilter,
|
||||||
'table': ClusterTable,
|
'table': ClusterTable,
|
||||||
'url': 'virtualization:cluster_list',
|
'url': 'virtualization:cluster_list',
|
||||||
}),
|
}),
|
||||||
('virtualmachine', {
|
('virtualmachine', {
|
||||||
'queryset': VirtualMachine.objects.select_related(
|
'queryset': VirtualMachine.objects.prefetch_related(
|
||||||
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
|
'cluster', 'tenant', 'platform', 'primary_ip4', 'primary_ip6',
|
||||||
),
|
),
|
||||||
'filter': VirtualMachineFilter,
|
'filter': VirtualMachineFilter,
|
||||||
@ -224,7 +224,7 @@ class HomeView(View):
|
|||||||
'stats': stats,
|
'stats': stats,
|
||||||
'topology_maps': TopologyMap.objects.filter(site__isnull=True),
|
'topology_maps': TopologyMap.objects.filter(site__isnull=True),
|
||||||
'report_results': ReportResult.objects.order_by('-created')[:10],
|
'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):
|
class SecretViewSet(ModelViewSet):
|
||||||
queryset = Secret.objects.select_related(
|
queryset = Secret.objects.prefetch_related(
|
||||||
'device__primary_ip4', 'device__primary_ip6', 'role',
|
'device__primary_ip4', 'device__primary_ip6', 'role', 'role__users', 'role__groups', 'tags',
|
||||||
).prefetch_related(
|
|
||||||
'role__users', 'role__groups', 'tags',
|
|
||||||
)
|
)
|
||||||
serializer_class = serializers.SecretSerializer
|
serializer_class = serializers.SecretSerializer
|
||||||
filterset_class = filters.SecretFilter
|
filterset_class = filters.SecretFilter
|
||||||
|
@ -69,7 +69,7 @@ class SecretRoleBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class SecretListView(PermissionRequiredMixin, ObjectListView):
|
class SecretListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'secrets.view_secret'
|
permission_required = 'secrets.view_secret'
|
||||||
queryset = Secret.objects.select_related('role', 'device')
|
queryset = Secret.objects.prefetch_related('role', 'device')
|
||||||
filter = filters.SecretFilter
|
filter = filters.SecretFilter
|
||||||
filter_form = forms.SecretFilterForm
|
filter_form = forms.SecretFilterForm
|
||||||
table = tables.SecretTable
|
table = tables.SecretTable
|
||||||
@ -247,7 +247,7 @@ class SecretBulkImportView(BulkImportView):
|
|||||||
|
|
||||||
class SecretBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class SecretBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'secrets.change_secret'
|
permission_required = 'secrets.change_secret'
|
||||||
queryset = Secret.objects.select_related('role', 'device')
|
queryset = Secret.objects.prefetch_related('role', 'device')
|
||||||
filter = filters.SecretFilter
|
filter = filters.SecretFilter
|
||||||
table = tables.SecretTable
|
table = tables.SecretTable
|
||||||
form = forms.SecretBulkEditForm
|
form = forms.SecretBulkEditForm
|
||||||
@ -256,7 +256,7 @@ class SecretBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class SecretBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class SecretBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'secrets.delete_secret'
|
permission_required = 'secrets.delete_secret'
|
||||||
queryset = Secret.objects.select_related('role', 'device')
|
queryset = Secret.objects.prefetch_related('role', 'device')
|
||||||
filter = filters.SecretFilter
|
filter = filters.SecretFilter
|
||||||
table = tables.SecretTable
|
table = tables.SecretTable
|
||||||
default_return_url = 'secrets:secret_list'
|
default_return_url = 'secrets:secret_list'
|
||||||
|
@ -35,10 +35,8 @@ class TenantGroupViewSet(ModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class TenantViewSet(CustomFieldModelViewSet):
|
class TenantViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Tenant.objects.select_related(
|
queryset = Tenant.objects.prefetch_related(
|
||||||
'group'
|
'group', 'tags'
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
circuit_count=get_subquery(Circuit, 'tenant'),
|
circuit_count=get_subquery(Circuit, 'tenant'),
|
||||||
device_count=get_subquery(Device, 'tenant'),
|
device_count=get_subquery(Device, 'tenant'),
|
||||||
|
@ -56,7 +56,7 @@ class TenantGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class TenantListView(PermissionRequiredMixin, ObjectListView):
|
class TenantListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'tenancy.view_tenant'
|
permission_required = 'tenancy.view_tenant'
|
||||||
queryset = Tenant.objects.select_related('group')
|
queryset = Tenant.objects.prefetch_related('group')
|
||||||
filter = filters.TenantFilter
|
filter = filters.TenantFilter
|
||||||
filter_form = forms.TenantFilterForm
|
filter_form = forms.TenantFilterForm
|
||||||
table = tables.TenantTable
|
table = tables.TenantTable
|
||||||
@ -115,7 +115,7 @@ class TenantBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class TenantBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class TenantBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'tenancy.change_tenant'
|
permission_required = 'tenancy.change_tenant'
|
||||||
queryset = Tenant.objects.select_related('group')
|
queryset = Tenant.objects.prefetch_related('group')
|
||||||
filter = filters.TenantFilter
|
filter = filters.TenantFilter
|
||||||
table = tables.TenantTable
|
table = tables.TenantTable
|
||||||
form = forms.TenantBulkEditForm
|
form = forms.TenantBulkEditForm
|
||||||
@ -124,7 +124,7 @@ class TenantBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class TenantBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class TenantBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'tenancy.delete_tenant'
|
permission_required = 'tenancy.delete_tenant'
|
||||||
queryset = Tenant.objects.select_related('group')
|
queryset = Tenant.objects.prefetch_related('group')
|
||||||
filter = filters.TenantFilter
|
filter = filters.TenantFilter
|
||||||
table = tables.TenantTable
|
table = tables.TenantTable
|
||||||
default_return_url = 'tenancy:tenant_list'
|
default_return_url = 'tenancy:tenant_list'
|
||||||
|
@ -40,10 +40,8 @@ class ClusterGroupViewSet(ModelViewSet):
|
|||||||
|
|
||||||
|
|
||||||
class ClusterViewSet(CustomFieldModelViewSet):
|
class ClusterViewSet(CustomFieldModelViewSet):
|
||||||
queryset = Cluster.objects.select_related(
|
queryset = Cluster.objects.prefetch_related(
|
||||||
'type', 'group', 'site',
|
'type', 'group', 'site', 'tags'
|
||||||
).prefetch_related(
|
|
||||||
'tags'
|
|
||||||
).annotate(
|
).annotate(
|
||||||
device_count=get_subquery(Device, 'cluster'),
|
device_count=get_subquery(Device, 'cluster'),
|
||||||
virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
|
virtualmachine_count=get_subquery(VirtualMachine, 'cluster')
|
||||||
@ -57,9 +55,9 @@ class ClusterViewSet(CustomFieldModelViewSet):
|
|||||||
#
|
#
|
||||||
|
|
||||||
class VirtualMachineViewSet(CustomFieldModelViewSet):
|
class VirtualMachineViewSet(CustomFieldModelViewSet):
|
||||||
queryset = VirtualMachine.objects.select_related(
|
queryset = VirtualMachine.objects.prefetch_related(
|
||||||
'cluster__site', 'role', 'tenant', 'platform', 'primary_ip4', 'primary_ip6'
|
'cluster__site', 'role', 'tenant', 'platform', 'primary_ip4', 'primary_ip6', 'tags'
|
||||||
).prefetch_related('tags')
|
)
|
||||||
filterset_class = filters.VirtualMachineFilter
|
filterset_class = filters.VirtualMachineFilter
|
||||||
|
|
||||||
def get_serializer_class(self):
|
def get_serializer_class(self):
|
||||||
@ -86,7 +84,9 @@ class VirtualMachineViewSet(CustomFieldModelViewSet):
|
|||||||
class InterfaceViewSet(ModelViewSet):
|
class InterfaceViewSet(ModelViewSet):
|
||||||
queryset = Interface.objects.filter(
|
queryset = Interface.objects.filter(
|
||||||
virtual_machine__isnull=False
|
virtual_machine__isnull=False
|
||||||
).select_related('virtual_machine').prefetch_related('tags')
|
).prefetch_related(
|
||||||
|
'virtual_machine', 'tags'
|
||||||
|
)
|
||||||
serializer_class = serializers.InterfaceSerializer
|
serializer_class = serializers.InterfaceSerializer
|
||||||
filterset_class = filters.InterfaceFilter
|
filterset_class = filters.InterfaceFilter
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
for family in [4, 6]:
|
for family in [4, 6]:
|
||||||
ip_choices = [(None, '---------')]
|
ip_choices = [(None, '---------')]
|
||||||
# Collect interface IPs
|
# 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
|
family=family, interface__virtual_machine=self.instance
|
||||||
)
|
)
|
||||||
if interface_ips:
|
if interface_ips:
|
||||||
@ -386,7 +386,7 @@ class VirtualMachineForm(BootstrapMixin, TenancyForm, CustomFieldForm):
|
|||||||
])
|
])
|
||||||
)
|
)
|
||||||
# Collect NAT IPs
|
# 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
|
family=family, nat_inside__interface__virtual_machine=self.instance
|
||||||
)
|
)
|
||||||
if nat_ips:
|
if nat_ips:
|
||||||
|
@ -96,7 +96,7 @@ class ClusterGroupBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
|||||||
|
|
||||||
class ClusterListView(PermissionRequiredMixin, ObjectListView):
|
class ClusterListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'virtualization.view_cluster'
|
permission_required = 'virtualization.view_cluster'
|
||||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||||
table = tables.ClusterTable
|
table = tables.ClusterTable
|
||||||
filter = filters.ClusterFilter
|
filter = filters.ClusterFilter
|
||||||
filter_form = forms.ClusterFilterForm
|
filter_form = forms.ClusterFilterForm
|
||||||
@ -109,7 +109,7 @@ class ClusterView(PermissionRequiredMixin, View):
|
|||||||
def get(self, request, pk):
|
def get(self, request, pk):
|
||||||
|
|
||||||
cluster = get_object_or_404(Cluster, pk=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'
|
'site', 'rack', 'tenant', 'device_type__manufacturer'
|
||||||
)
|
)
|
||||||
device_table = DeviceTable(list(devices), orderable=False)
|
device_table = DeviceTable(list(devices), orderable=False)
|
||||||
@ -148,7 +148,7 @@ class ClusterBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'virtualization.change_cluster'
|
permission_required = 'virtualization.change_cluster'
|
||||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||||
filter = filters.ClusterFilter
|
filter = filters.ClusterFilter
|
||||||
table = tables.ClusterTable
|
table = tables.ClusterTable
|
||||||
form = forms.ClusterBulkEditForm
|
form = forms.ClusterBulkEditForm
|
||||||
@ -157,7 +157,7 @@ class ClusterBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class ClusterBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'virtualization.delete_cluster'
|
permission_required = 'virtualization.delete_cluster'
|
||||||
queryset = Cluster.objects.select_related('type', 'group', 'site')
|
queryset = Cluster.objects.prefetch_related('type', 'group', 'site')
|
||||||
filter = filters.ClusterFilter
|
filter = filters.ClusterFilter
|
||||||
table = tables.ClusterTable
|
table = tables.ClusterTable
|
||||||
default_return_url = 'virtualization:cluster_list'
|
default_return_url = 'virtualization:cluster_list'
|
||||||
@ -253,7 +253,7 @@ class ClusterRemoveDevicesView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
class VirtualMachineListView(PermissionRequiredMixin, ObjectListView):
|
class VirtualMachineListView(PermissionRequiredMixin, ObjectListView):
|
||||||
permission_required = 'virtualization.view_virtualmachine'
|
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 = filters.VirtualMachineFilter
|
||||||
filter_form = forms.VirtualMachineFilterForm
|
filter_form = forms.VirtualMachineFilterForm
|
||||||
table = tables.VirtualMachineDetailTable
|
table = tables.VirtualMachineDetailTable
|
||||||
@ -265,7 +265,7 @@ class VirtualMachineView(PermissionRequiredMixin, View):
|
|||||||
|
|
||||||
def get(self, request, pk):
|
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)
|
interfaces = Interface.objects.filter(virtual_machine=virtualmachine)
|
||||||
services = Service.objects.filter(virtual_machine=virtualmachine)
|
services = Service.objects.filter(virtual_machine=virtualmachine)
|
||||||
|
|
||||||
@ -309,7 +309,7 @@ class VirtualMachineBulkImportView(PermissionRequiredMixin, BulkImportView):
|
|||||||
|
|
||||||
class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
||||||
permission_required = 'virtualization.change_virtualmachine'
|
permission_required = 'virtualization.change_virtualmachine'
|
||||||
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role')
|
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role')
|
||||||
filter = filters.VirtualMachineFilter
|
filter = filters.VirtualMachineFilter
|
||||||
table = tables.VirtualMachineTable
|
table = tables.VirtualMachineTable
|
||||||
form = forms.VirtualMachineBulkEditForm
|
form = forms.VirtualMachineBulkEditForm
|
||||||
@ -318,7 +318,7 @@ class VirtualMachineBulkEditView(PermissionRequiredMixin, BulkEditView):
|
|||||||
|
|
||||||
class VirtualMachineBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
class VirtualMachineBulkDeleteView(PermissionRequiredMixin, BulkDeleteView):
|
||||||
permission_required = 'virtualization.delete_virtualmachine'
|
permission_required = 'virtualization.delete_virtualmachine'
|
||||||
queryset = VirtualMachine.objects.select_related('cluster', 'tenant', 'role')
|
queryset = VirtualMachine.objects.prefetch_related('cluster', 'tenant', 'role')
|
||||||
filter = filters.VirtualMachineFilter
|
filter = filters.VirtualMachineFilter
|
||||||
table = tables.VirtualMachineTable
|
table = tables.VirtualMachineTable
|
||||||
default_return_url = 'virtualization:virtualmachine_list'
|
default_return_url = 'virtualization:virtualmachine_list'
|
||||||
|
Loading…
Reference in New Issue
Block a user