From 18fbb9eba198a43cb2fda01d1fc57e2a3946d2eb Mon Sep 17 00:00:00 2001 From: Sander Steffann Date: Mon, 21 Oct 2019 14:52:40 +0200 Subject: [PATCH] Move class queryset to cached property Using ContentType on class definition breaks when the database tables haven't been created yet --- netbox/dcim/api/views.py | 35 +++++++++++++++++++++-------------- netbox/dcim/views.py | 39 +++++++++++++++++++++++---------------- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/netbox/dcim/api/views.py b/netbox/dcim/api/views.py index fd3224c15..18ad69eeb 100644 --- a/netbox/dcim/api/views.py +++ b/netbox/dcim/api/views.py @@ -5,6 +5,7 @@ from django.contrib.contenttypes.models import ContentType from django.db.models import Count, F from django.http import HttpResponseForbidden from django.shortcuts import get_object_or_404 +from django.utils.functional import cached_property from drf_yasg import openapi from drf_yasg.openapi import Parameter from drf_yasg.utils import swagger_auto_schema @@ -510,14 +511,17 @@ class InventoryItemViewSet(ModelViewSet): # class ConsoleConnectionViewSet(ListModelMixin, GenericViewSet): - queryset = ConsolePort.objects.prefetch_related( - 'device', 'connected_endpoint__device' - ).filter( - connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort) - ) serializer_class = serializers.ConsolePortSerializer filterset_class = filters.ConsoleConnectionFilter + @cached_property + def queryset(self): + return ConsolePort.objects.prefetch_related( + 'device', 'connected_endpoint__device' + ).filter( + connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort) + ) + class PowerConnectionViewSet(ListModelMixin, GenericViewSet): queryset = PowerPort.objects.prefetch_related( @@ -530,18 +534,21 @@ class PowerConnectionViewSet(ListModelMixin, GenericViewSet): class InterfaceConnectionViewSet(ListModelMixin, GenericViewSet): - queryset = Interface.objects.prefetch_related( - 'device', 'connected_endpoint__device' - ).filter( - # Avoid duplicate connections by only selecting the lower PK in a connected pair - connected_endpoint_type=ContentType.objects.get_for_model(Interface), - pk__lt=F('connected_endpoint_id') - ).order_by( - 'device' - ) serializer_class = serializers.InterfaceConnectionSerializer filterset_class = filters.InterfaceConnectionFilter + @cached_property + def queryset(self): + return Interface.objects.prefetch_related( + 'device', 'connected_endpoint__device' + ).filter( + # Avoid duplicate connections by only selecting the lower PK in a connected pair + connected_endpoint_type=ContentType.objects.get_for_model(Interface), + pk__lt=F('connected_endpoint_id') + ).order_by( + 'device' + ) + # # Cables diff --git a/netbox/dcim/views.py b/netbox/dcim/views.py index f91ff8bee..3d55c4330 100644 --- a/netbox/dcim/views.py +++ b/netbox/dcim/views.py @@ -10,6 +10,7 @@ from django.db.models import Count, F from django.forms import modelformset_factory from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse +from django.utils.functional import cached_property from django.utils.html import escape from django.utils.http import is_safe_url from django.utils.safestring import mark_safe @@ -1876,18 +1877,21 @@ class CableBulkDeleteView(PermissionRequiredMixin, BulkDeleteView): class ConsoleConnectionsListView(PermissionRequiredMixin, ObjectListView): permission_required = ('dcim.view_consoleport', 'dcim.view_consoleserverport') - queryset = ConsolePort.objects.prefetch_related( - 'device', 'connected_endpoint__device' - ).filter( - connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort) - ).order_by( - 'cable', # 'connected_endpoint__device__name', 'connected_endpoint__name' - ) filter = filters.ConsoleConnectionFilter filter_form = forms.ConsoleConnectionFilterForm table = tables.ConsoleConnectionTable template_name = 'dcim/console_connections_list.html' + @cached_property + def queryset(self): + return ConsolePort.objects.prefetch_related( + 'device', 'connected_endpoint__device' + ).filter( + connected_endpoint_type=ContentType.objects.get_for_model(ConsoleServerPort) + ).order_by( + 'cable', # 'connected_endpoint__device__name', 'connected_endpoint__name' + ) + def queryset_to_csv(self): csv_data = [ # Headers @@ -1938,20 +1942,23 @@ class PowerConnectionsListView(PermissionRequiredMixin, ObjectListView): class InterfaceConnectionsListView(PermissionRequiredMixin, ObjectListView): permission_required = 'dcim.view_interface' - queryset = Interface.objects.prefetch_related( - 'device', 'cable', 'connected_endpoint__device' - ).filter( - # Avoid duplicate connections by only selecting the lower PK in a connected pair - connected_endpoint_type=ContentType.objects.get_for_model(Interface), - pk__lt=F('connected_endpoint_id') - ).order_by( - 'device' - ) filter = filters.InterfaceConnectionFilter filter_form = forms.InterfaceConnectionFilterForm table = tables.InterfaceConnectionTable template_name = 'dcim/interface_connections_list.html' + @cached_property + def queryset(self): + return Interface.objects.prefetch_related( + 'device', 'cable', 'connected_endpoint__device' + ).filter( + # Avoid duplicate connections by only selecting the lower PK in a connected pair + connected_endpoint_type=ContentType.objects.get_for_model(Interface), + pk__lt=F('connected_endpoint_id') + ).order_by( + 'device' + ) + def queryset_to_csv(self): csv_data = [ # Headers