From 23b7ad5067c0574d844cf5fe73822afa21226f3d Mon Sep 17 00:00:00 2001 From: Dirk Julich Date: Fri, 19 Jun 2026 16:45:14 +0200 Subject: [PATCH] [devel backport][AAP-70902] Use _actor_role_filter() in UnifiedJobTemplate.accessible_pk_qs() (#16513) * Use _actor_role_filter() in UnifiedJobTemplate.accessible_pk_qs() Replace `role__in=accessor.has_roles.all()` with the optimized `_actor_role_filter()` subquery pattern from django-ansible-base. The old pattern causes a 3-table JOIN through RoleUserAssignment -> ObjectRole -> RoleEvaluation on every non-superuser request. _actor_role_filter() skips the ObjectRole table entirely by using a direct subquery on RoleUserAssignment.object_role_id, eliminating the intermediate JOIN and reducing query time for /api/v2/unified_jobs/ requests by non-superusers. --- awx/main/models/unified_jobs.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index bca6b2c4d6..2a651ffa1c 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -234,7 +234,11 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, ExecutionEn dab_role_cts = permission_registry.content_type_model.objects.get_for_models(*role_subclasses).values() return ( - RoleEvaluation.objects.filter(role__in=accessor.has_roles.all(), codename__in=all_codenames, content_type_id__in=[ct.id for ct in dab_role_cts]) + RoleEvaluation.objects.filter( + **RoleEvaluation._actor_role_filter(accessor), + codename__in=all_codenames, + content_type_id__in=[ct.id for ct in dab_role_cts], + ) .values_list('object_id') .distinct() )