diff --git a/label_studio/data_manager/managers.py b/label_studio/data_manager/managers.py index 70c9b81056a5..9abd636d04bb 100644 --- a/label_studio/data_manager/managers.py +++ b/label_studio/data_manager/managers.py @@ -494,6 +494,10 @@ def prepared(self, prepare_params=None): :param prepare_params: prepare params with project, filters, orderings, etc :return: ordered and filtered queryset + + Note: For multi-project queries, filters and ordering will use the first project's + configuration (label config, custom fields, etc.). This is backwards compatible + with single-project queries. """ from projects.models import Project @@ -502,7 +506,14 @@ def prepared(self, prepare_params=None): if prepare_params is None: return queryset - project = Project.objects.get(pk=prepare_params.project) + # Get the project for filter/ordering configuration + # For multi-project queries, use the first project's configuration + if prepare_params.is_multi_project: + project = Project.objects.get(pk=prepare_params.projects[0]) + else: + # Backwards compatible: prepare_params.project is an int + project = Project.objects.get(pk=prepare_params.project) + request = prepare_params.request queryset = apply_filters(queryset, prepare_params.filters, project, request) queryset = apply_ordering(queryset, prepare_params.ordering, project, request, view_data=prepare_params.data) @@ -774,7 +785,11 @@ def get_queryset( def only_filtered(self, prepare_params=None): request = prepare_params.request - queryset = TaskQuerySet(self.model).filter(project=prepare_params.project) + # Support both single and multiple projects + if prepare_params.is_multi_project: + queryset = TaskQuerySet(self.model).filter(project__in=prepare_params.projects) + else: + queryset = TaskQuerySet(self.model).filter(project=prepare_params.project) fields_for_filter_ordering = get_fields_for_filter_ordering(prepare_params) queryset = self.annotate_queryset(queryset, fields_for_evaluation=fields_for_filter_ordering, request=request) return queryset.prepared(prepare_params=prepare_params) diff --git a/label_studio/data_manager/prepare_params.py b/label_studio/data_manager/prepare_params.py index 131daa3ac25d..ad087df49638 100644 --- a/label_studio/data_manager/prepare_params.py +++ b/label_studio/data_manager/prepare_params.py @@ -37,13 +37,25 @@ class SelectedItems(BaseModel): class PrepareParams(BaseModel): - project: int + project: Union[int, List[int]] # Support both single project and multiple projects ordering: List[str] = [] selectedItems: Optional[SelectedItems] = None filters: Optional[Filters] = None data: Optional[dict] = None request: Optional[Any] = None + @property + def projects(self) -> List[int]: + """Get project IDs as a list, whether single or multiple were provided.""" + if isinstance(self.project, list): + return self.project + return [self.project] + + @property + def is_multi_project(self) -> bool: + """Check if this PrepareParams includes multiple projects.""" + return isinstance(self.project, list) and len(self.project) > 1 + class CustomEnum(Enum): def __init__(self, value, description):