From cd2f70ce10f67b84536f0761be51b070f68fd102 Mon Sep 17 00:00:00 2001 From: Alex Dusenbery Date: Tue, 30 Apr 2024 12:03:24 -0400 Subject: [PATCH] feat: limit the number of resulting learners in Django admin manage learners view ...so that we can support customers with a very large number of learners ENT-8850 --- CHANGELOG.rst | 6 ++++++ enterprise/__init__.py | 2 +- enterprise/admin/views.py | 36 +++++++++++++++++++++++++----------- enterprise/constants.py | 3 +++ 4 files changed, 35 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 2d1b7b1995..873eee070d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -15,6 +15,12 @@ Change Log Unreleased ---------- +* nothing unreleased + +[4.17.0] +-------- +* feat: limit the number of resulting learners in Django admin manage learners view + [4.16.5] -------- * feat: splitting out group membership serializer learner id into lms user ID and ecu ID diff --git a/enterprise/__init__.py b/enterprise/__init__.py index 14366bd1a1..dc908abd25 100644 --- a/enterprise/__init__.py +++ b/enterprise/__init__.py @@ -2,4 +2,4 @@ Your project description goes here. """ -__version__ = "4.16.5" +__version__ = "4.17.0" diff --git a/enterprise/admin/views.py b/enterprise/admin/views.py index 9addac150f..635c593c6b 100644 --- a/enterprise/admin/views.py +++ b/enterprise/admin/views.py @@ -37,7 +37,7 @@ from enterprise.api_client.discovery import get_course_catalog_api_service_client from enterprise.api_client.ecommerce import EcommerceApiClient from enterprise.api_client.sso_orchestrator import EnterpriseSSOOrchestratorApiClient, SsoOrchestratorClientError -from enterprise.constants import PAGE_SIZE +from enterprise.constants import DJANGO_ADMIN_MANAGE_LEARNERS_LIMIT, PAGE_SIZE from enterprise.errors import LinkUserToEnterpriseError from enterprise.models import ( EnrollmentNotificationEmailTemplate, @@ -357,7 +357,11 @@ def get_search_keyword(self, request): def get_enterprise_customer_user_queryset(self, request, search_keyword, customer_uuid, page_size=PAGE_SIZE): """ - Get the list of EnterpriseCustomerUsers we want to render. + Get the list of EnterpriseCustomerUsers we want to render. Note that, + if no ``search_keyword`` is provided, the resulting queryset will + only include up to some constant limit of results, so that we + can support searching for particular user records in customers + with very large numbers of learners. Arguments: request (HttpRequest): HTTP Request instance. @@ -367,16 +371,26 @@ def get_enterprise_customer_user_queryset(self, request, search_keyword, custome page_size (int): Number of learners displayed in each paginated set. """ page = request.GET.get('page', 1) - learners = EnterpriseCustomerUser.objects.filter(enterprise_customer__uuid=customer_uuid) - user_ids = learners.values_list('user_id', flat=True) - matching_users = User.objects.filter(pk__in=user_ids) if search_keyword is not None: - matching_users = matching_users.filter( - Q(email__icontains=search_keyword) | Q(username__icontains=search_keyword) - ) - matching_user_ids = matching_users.values_list('pk', flat=True) - learners = learners.filter(user_id__in=matching_user_ids) - return paginated_list(learners, page, page_size) + enterprise_learners = self._get_searched_enterprise_customer_users(search_keyword, customer_uuid) + else: + enterprise_learners = EnterpriseCustomerUser.objects.filter( + enterprise_customer__uuid=customer_uuid, + )[:DJANGO_ADMIN_MANAGE_LEARNERS_LIMIT] + return paginated_list(enterprise_learners, page, page_size) + + def _get_searched_enterprise_customer_users(self, search_keyword, customer_uuid): + """ + Helper to return a paginated list of enterprise customer users + who match some search criteria based on corresponding ``core.User`` records. + """ + matching_user_ids = User.objects.filter( + Q(email__icontains=search_keyword) | Q(username__icontains=search_keyword) + ).values_list('id', flat=True) + return EnterpriseCustomerUser.objects.filter( + enterprise_customer__uuid=customer_uuid, + user_id__in=matching_user_ids, + ) def get_pending_users_queryset(self, search_keyword, customer_uuid): """ diff --git a/enterprise/constants.py b/enterprise/constants.py index 15f4ac8ba4..da03e7896d 100644 --- a/enterprise/constants.py +++ b/enterprise/constants.py @@ -252,3 +252,6 @@ class FulfillmentTypes: ) ENTITY_ID_REGEX = r"<(\w+:)?EntityDescriptor.*?entityID=['\"](.*?)['\"].*?>" + +# Max learners included in the Admin Manage Learners page +DJANGO_ADMIN_MANAGE_LEARNERS_LIMIT = 10000