apply optimizations via standard method

This addresses the top-level resources in the v2
root view, focusing in order of priority,
reflecting use by the UI.

In several cases get_queryset logic from the view
is moved into the access class.

Most other cases involve adding a straightforward
select_related or prefetch_related entry.

All additional confirmed to be effective with the
django debug toolbar.
This commit is contained in:
AlanCoding
2019-05-01 19:24:15 -04:00
parent 1ce587025e
commit dbc65baa43
4 changed files with 31 additions and 46 deletions

View File

@@ -61,7 +61,7 @@ from wsgiref.util import FileWrapper
# AWX
from awx.main.tasks import send_notifications, update_inventory_computed_fields
from awx.main.access import get_user_queryset
from awx.main.access import get_user_queryset, HostAccess
from awx.api.filters import V1CredentialFilterBackend
from awx.api.generics import (
APIView, BaseUsersList, CopyAPIView, DeleteLastUnattachLabelMixin,
@@ -670,18 +670,6 @@ class ProjectList(ListCreateAPIView):
model = models.Project
serializer_class = serializers.ProjectSerializer
def get_queryset(self):
projects_qs = models.Project.accessible_objects(self.request.user, 'read_role')
projects_qs = projects_qs.select_related(
'organization',
'admin_role',
'use_role',
'update_role',
'read_role',
)
projects_qs = projects_qs.prefetch_related('last_job', 'created_by')
return projects_qs
class ProjectDetail(RelatedJobsPreventDeleteMixin, RetrieveUpdateDestroyAPIView):
@@ -1539,7 +1527,10 @@ class InventoryHostsList(HostRelatedSearchMixin, SubListCreateAttachDetachAPIVie
def get_queryset(self):
inventory = self.get_parent_object()
return getattrd(inventory, self.relationship).all()
qs = getattrd(inventory, self.relationship).all()
# Apply queryset optimizations
qs = qs.select_related(*HostAccess.select_related).prefetch_related(*HostAccess.prefetch_related)
return qs
class HostGroupsList(ControlledByScmMixin, SubListCreateAttachDetachAPIView):
@@ -4427,18 +4418,6 @@ class RoleList(ListAPIView):
permission_classes = (IsAuthenticated,)
search_fields = ('role_field', 'content_type__model',)
def get_queryset(self):
result = models.Role.visible_roles(self.request.user)
# Sanity check: is the requesting user an orphaned non-admin/auditor?
# if yes, make system admin/auditor mandatorily visible.
if not self.request.user.organizations.exists() and\
not self.request.user.is_superuser and\
not self.request.user.is_system_auditor:
mandatories = ('system_administrator', 'system_auditor')
super_qs = models.Role.objects.filter(singleton_name__in=mandatories)
result = result | super_qs
return result
class RoleDetail(RetrieveAPIView):

View File

@@ -115,12 +115,6 @@ class InventoryList(ListCreateAPIView):
model = Inventory
serializer_class = InventorySerializer
def get_queryset(self):
qs = Inventory.accessible_objects(self.request.user, 'read_role')
qs = qs.select_related('admin_role', 'read_role', 'update_role', 'use_role', 'adhoc_role')
qs = qs.prefetch_related('created_by', 'modified_by', 'organization')
return qs
class InventoryDetail(RelatedJobsPreventDeleteMixin, ControlledByScmMixin, RetrieveUpdateDestroyAPIView):

View File

@@ -167,7 +167,7 @@ class ApiV1PingView(APIView):
capacity=instance.capacity, version=instance.version))
sorted(response['instances'], key=operator.itemgetter('node'))
response['instance_groups'] = []
for instance_group in InstanceGroup.objects.all():
for instance_group in InstanceGroup.objects.prefetch_related('instances'):
response['instance_groups'].append(dict(name=instance_group.name,
capacity=instance_group.capacity,
instances=[x.hostname for x in instance_group.instances.all()]))