mirror of
https://github.com/ansible/awx.git
synced 2026-01-12 02:19:58 -03:30
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:
parent
1ce587025e
commit
dbc65baa43
@ -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):
|
||||
|
||||
|
||||
@ -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):
|
||||
|
||||
|
||||
@ -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()]))
|
||||
|
||||
@ -687,6 +687,7 @@ class OAuth2ApplicationAccess(BaseAccess):
|
||||
|
||||
model = OAuth2Application
|
||||
select_related = ('user',)
|
||||
prefetch_related = ('organization', 'oauth2accesstoken_set')
|
||||
|
||||
def filtered_queryset(self):
|
||||
org_access_qs = Organization.accessible_objects(self.user, 'member_role')
|
||||
@ -725,6 +726,7 @@ class OAuth2TokenAccess(BaseAccess):
|
||||
model = OAuth2AccessToken
|
||||
|
||||
select_related = ('user', 'application')
|
||||
prefetch_related = ('refresh_token',)
|
||||
|
||||
def filtered_queryset(self):
|
||||
org_access_qs = Organization.objects.filter(
|
||||
@ -826,7 +828,7 @@ class InventoryAccess(BaseAccess):
|
||||
'''
|
||||
|
||||
model = Inventory
|
||||
select_related = ('created_by', 'modified_by', 'organization',)
|
||||
prefetch_related = ('created_by', 'modified_by', 'organization')
|
||||
|
||||
def filtered_queryset(self, allowed=None, ad_hoc=None):
|
||||
return self.model.accessible_objects(self.user, 'read_role')
|
||||
@ -1090,8 +1092,8 @@ class InventoryUpdateAccess(BaseAccess):
|
||||
'''
|
||||
|
||||
model = InventoryUpdate
|
||||
select_related = ('created_by', 'modified_by', 'inventory_source__inventory',)
|
||||
prefetch_related = ('unified_job_template', 'instance_group', 'credentials',)
|
||||
select_related = ('created_by', 'modified_by', 'inventory_source',)
|
||||
prefetch_related = ('unified_job_template', 'instance_group', 'credentials__credential_type', 'inventory', 'source_script')
|
||||
|
||||
def filtered_queryset(self):
|
||||
return self.model.objects.filter(inventory_source__inventory__in=Inventory.accessible_pk_qs(self.user, 'read_role'))
|
||||
@ -1105,11 +1107,7 @@ class InventoryUpdateAccess(BaseAccess):
|
||||
return self.user in obj.inventory_source.inventory.admin_role
|
||||
|
||||
def can_start(self, obj, validate_license=True):
|
||||
# For relaunching
|
||||
if obj and obj.inventory_source:
|
||||
access = InventorySourceAccess(self.user)
|
||||
return access.can_start(obj.inventory_source, validate_license=validate_license)
|
||||
return False
|
||||
return InventorySourceAccess(self.user).can_start(obj, validate_license=validate_license)
|
||||
|
||||
@check_superuser
|
||||
def can_delete(self, obj):
|
||||
@ -1127,6 +1125,7 @@ class CredentialTypeAccess(BaseAccess):
|
||||
'''
|
||||
|
||||
model = CredentialType
|
||||
prefetch_related = ('created_by', 'modified_by',)
|
||||
|
||||
def can_read(self, obj):
|
||||
return True
|
||||
@ -1363,7 +1362,8 @@ class ProjectAccess(NotificationAttachMixin, BaseAccess):
|
||||
'''
|
||||
|
||||
model = Project
|
||||
select_related = ('modified_by', 'credential', 'current_job', 'last_job',)
|
||||
select_related = ('credential',)
|
||||
prefetch_related = ('modified_by', 'created_by', 'organization', 'last_job', 'current_job')
|
||||
notification_attach_roles = ['admin_role']
|
||||
|
||||
def filtered_queryset(self):
|
||||
@ -1856,7 +1856,7 @@ class WorkflowJobTemplateNodeAccess(BaseAccess):
|
||||
'''
|
||||
model = WorkflowJobTemplateNode
|
||||
prefetch_related = ('success_nodes', 'failure_nodes', 'always_nodes',
|
||||
'unified_job_template', 'credentials',)
|
||||
'unified_job_template', 'credentials', 'workflow_job_template')
|
||||
|
||||
def filtered_queryset(self):
|
||||
return self.model.objects.filter(
|
||||
@ -1948,9 +1948,8 @@ class WorkflowJobNodeAccess(BaseAccess):
|
||||
Deletion must happen as a cascade delete from the workflow job.
|
||||
'''
|
||||
model = WorkflowJobNode
|
||||
select_related = ('unified_job_template', 'job',)
|
||||
prefetch_related = ('success_nodes', 'failure_nodes', 'always_nodes',
|
||||
'credentials',)
|
||||
prefetch_related = ('unified_job_template', 'job', 'workflow_job', 'credentials',
|
||||
'success_nodes', 'failure_nodes', 'always_nodes',)
|
||||
|
||||
def filtered_queryset(self):
|
||||
return self.model.objects.filter(
|
||||
@ -2497,6 +2496,7 @@ class NotificationTemplateAccess(BaseAccess):
|
||||
I can see/use a notification_template if I have permission to
|
||||
'''
|
||||
model = NotificationTemplate
|
||||
prefetch_related = ('created_by', 'modified_by', 'organization')
|
||||
|
||||
def filtered_queryset(self):
|
||||
return self.model.objects.filter(
|
||||
@ -2683,6 +2683,7 @@ class ActivityStreamAccess(BaseAccess):
|
||||
class CustomInventoryScriptAccess(BaseAccess):
|
||||
|
||||
model = CustomInventoryScript
|
||||
prefetch_related = ('created_by', 'modified_by', 'organization')
|
||||
|
||||
def filtered_queryset(self):
|
||||
return self.model.accessible_objects(self.user, 'read_role').all()
|
||||
@ -2716,6 +2717,17 @@ class RoleAccess(BaseAccess):
|
||||
'''
|
||||
|
||||
model = Role
|
||||
prefetch_related = ('content_type',)
|
||||
|
||||
def filtered_queryset(self):
|
||||
result = Role.visible_roles(self.user)
|
||||
# Sanity check: is the requesting user an orphaned non-admin/auditor?
|
||||
# if yes, make system admin/auditor mandatorily visible.
|
||||
if not self.user.is_superuser and not self.user.is_system_auditor and not self.user.organizations.exists():
|
||||
mandatories = ('system_administrator', 'system_auditor')
|
||||
super_qs = Role.objects.filter(singleton_name__in=mandatories)
|
||||
result = result | super_qs
|
||||
return result
|
||||
|
||||
def can_read(self, obj):
|
||||
if not obj:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user