@@ -595,6 +595,9 @@ def get_queryset(self) -> QuerySet:
595595 parameters = [
596596 apidocs .query_parameter ("search" , str , description = "Filter scopes by display name" ),
597597 apidocs .query_parameter ("org" , str , description = "Filter scopes by org" ),
598+ apidocs .query_parameter (
599+ "orgs" , str , description = "Filter scopes by multiple orgs (comma separated list of orgs)"
600+ ),
598601 apidocs .query_parameter ("page" , int , description = "Page number for pagination" ),
599602 apidocs .query_parameter ("page_size" , int , description = "Number of items per page" ),
600603 apidocs .query_parameter (
@@ -631,6 +634,7 @@ class ScopesAPIView(generics.ListAPIView):
631634
632635 - search (Optional): Search term to filter scopes by display name
633636 - org (Optional): Filter scopes by org
637+ - orgs (Optional): Filter scopes by multiple orgs (comma separated list of orgs)
634638 - page (Optional): Page number for pagination
635639 - page_size (Optional): Number of items per page
636640 - scope_type (Optional): Filter scopes by type. Supported values are `course` and `library`.
@@ -700,7 +704,7 @@ def _get_courses_queryset(
700704 allowed_ids : set | None = None ,
701705 allowed_orgs : set | None = None ,
702706 search : str = "" ,
703- org : str = "" ,
707+ orgs : set [ str ] | None = None ,
704708 ) -> QuerySet :
705709 """Return a CourseOverview queryset projected to the unified scope shape.
706710
@@ -717,8 +721,8 @@ def _get_courses_queryset(
717721 qs = qs .none ()
718722 else :
719723 qs = qs .filter (combined_filter )
720- if org :
721- qs = qs .filter (org = org )
724+ if orgs :
725+ qs = qs .filter (org__in = orgs )
722726 if search :
723727 qs = qs .filter (display_name__icontains = search )
724728 return qs .annotate (
@@ -738,7 +742,7 @@ def _get_libraries_queryset(
738742 allowed_pairs : set | None = None ,
739743 allowed_orgs : set | None = None ,
740744 search : str = "" ,
741- org : str = "" ,
745+ orgs : set [ str ] | None = None ,
742746 ) -> QuerySet :
743747 """Return a ContentLibrary queryset projected to the unified scope shape.
744748
@@ -759,8 +763,8 @@ def _get_libraries_queryset(
759763 qs = qs .none ()
760764 else :
761765 qs = qs .filter (combined )
762- if org :
763- qs = qs .filter (org__short_name = org )
766+ if orgs :
767+ qs = qs .filter (org__short_name__in = orgs )
764768 if search :
765769 qs = qs .filter (learning_package__title__icontains = search )
766770 return qs .annotate (
@@ -785,7 +789,7 @@ def _get_allowed_scope_queryset(
785789 queryset_builder : callable ,
786790 extract_ids : callable ,
787791 search : str = "" ,
788- org : str = "" ,
792+ orgs : set [ str ] | None = None ,
789793 ) -> QuerySet :
790794 """Resolve allowed scopes from Casbin and return a filtered queryset.
791795
@@ -811,7 +815,7 @@ def _get_allowed_scope_queryset(
811815 specific_scopes = [s for s in allowed_scopes if not isinstance (s , glob_cls )]
812816 allowed_ids = extract_ids (specific_scopes )
813817 allowed_orgs = {s .org for s in allowed_scopes if isinstance (s , glob_cls )}
814- return queryset_builder (allowed_ids , allowed_orgs , search = search , org = org )
818+ return queryset_builder (allowed_ids , allowed_orgs , search = search , orgs = orgs )
815819
816820 def _build_queryset (self , courses_qs : QuerySet | None , libraries_qs : QuerySet | None ) -> QuerySet :
817821 """Union the provided querysets and sort deterministically.
@@ -834,17 +838,24 @@ def get_queryset(self) -> QuerySet:
834838 scope_type = params_serializer .validated_data ["scope_type" ]
835839 search = params_serializer .validated_data ["search" ]
836840 org = params_serializer .validated_data .get ("org" , "" )
841+ orgs_param = params_serializer .validated_data .get ("orgs" , [])
842+
843+ orgs = set ()
844+ orgs .update (orgs_param )
845+
846+ if org :
847+ orgs .add (org )
837848
838849 # Staff and superusers can see all scopes, skip permission filtering.
839850 if user .is_staff or user .is_superuser :
840851 return self ._build_queryset (
841852 courses_qs = (
842- self ._get_courses_queryset (search = search , org = org )
853+ self ._get_courses_queryset (search = search , orgs = orgs )
843854 if scope_type != ScopesTypeField .LIBRARY
844855 else None
845856 ),
846857 libraries_qs = (
847- self ._get_libraries_queryset (search = search , org = org )
858+ self ._get_libraries_queryset (search = search , orgs = orgs )
848859 if scope_type != ScopesTypeField .COURSE
849860 else None
850861 ),
@@ -867,7 +878,7 @@ def get_permission(scope_cls):
867878 queryset_builder = self ._get_courses_queryset ,
868879 extract_ids = lambda scopes : {s .external_key for s in scopes },
869880 search = search ,
870- org = org ,
881+ orgs = orgs ,
871882 )
872883
873884 libraries_qs = None
@@ -882,7 +893,7 @@ def get_permission(scope_cls):
882893 (s .external_key .split (":" )[1 ], s .external_key .split (":" )[2 ]) for s in scopes
883894 },
884895 search = search ,
885- org = org ,
896+ orgs = orgs ,
886897 )
887898
888899 # Union the requested querysets and sort by org at the DB level.
0 commit comments