From a5334d9e0686753fe99a837d298de273b1f20d0c Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Tue, 25 Nov 2025 04:13:48 +0000 Subject: [PATCH] Fix for parametric part table - Only display parameters for which we know there is a value --- src/backend/InvenTree/common/api.py | 22 +++++++++++++++ src/backend/InvenTree/common/filters.py | 37 ++++++++++++++++++------- 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/src/backend/InvenTree/common/api.py b/src/backend/InvenTree/common/api.py index 14894d8681..8b42d6dc13 100644 --- a/src/backend/InvenTree/common/api.py +++ b/src/backend/InvenTree/common/api.py @@ -27,6 +27,7 @@ from rest_framework.exceptions import NotAcceptable, NotFound, PermissionDenied from rest_framework.permissions import IsAdminUser, IsAuthenticated from rest_framework.response import Response from rest_framework.views import APIView +from sql_util.utils import SubqueryCount import common.filters import common.models @@ -820,6 +821,27 @@ class ParameterTemplateFilter(FilterSet): queryset, 'model_type', value, allow_null=True ) + exists_for_model = rest_filters.CharFilter( + method='filter_exists_for_model', label='Exists For Model' + ) + + def filter_exists_for_model(self, queryset, name, value): + """Filter queryset to include only ParameterTemplates which have at least one Parameter for the given model type.""" + content_type = common.filters.determine_content_type(value) + + if not content_type: + return queryset.none() + + # Annotate the queryset to determine which ParameterTemplates have at least one Parameter for the given model type + queryset = queryset.annotate( + parameter_count=SubqueryCount( + 'parameters', filter=Q(model_type=content_type) + ) + ) + + # Return only those ParameterTemplates which have at least one Parameter for the given model type + return queryset.filter(parameter_count__gt=0) + class ParameterTemplateMixin: """Mixin class for ParameterTemplate views.""" diff --git a/src/backend/InvenTree/common/filters.py b/src/backend/InvenTree/common/filters.py index 1600255634..7bde1b7f4e 100644 --- a/src/backend/InvenTree/common/filters.py +++ b/src/backend/InvenTree/common/filters.py @@ -21,22 +21,17 @@ import InvenTree.conversion import InvenTree.helpers -def filter_content_type( - queryset, field_name: str, content_type: str | int | None, allow_null: bool = True -): - """Filter a queryset by content type. +def determine_content_type(content_type: str | int | None) -> ContentType | None: + """Determine a ContentType instance from a string or integer input. Arguments: - queryset: The queryset to filter. - field_name: The name of the content type field within the current model context. - content_type: The content type to filter by (name or ID). - allow_null: If True, include entries with null content type. + content_type: The content type to resolve (name or ID). Returns: - Filtered queryset. + ContentType instance if found, else None. """ if content_type is None: - return queryset + return None ct = None @@ -59,6 +54,28 @@ def filter_content_type( # Next, try to resolve the content type via a model name ct = ContentType.objects.filter(model__iexact=content_type).first() + return ct + + +def filter_content_type( + queryset, field_name: str, content_type: str | int | None, allow_null: bool = True +): + """Filter a queryset by content type. + + Arguments: + queryset: The queryset to filter. + field_name: The name of the content type field within the current model context. + content_type: The content type to filter by (name or ID). + allow_null: If True, include entries with null content type. + + Returns: + Filtered queryset. + """ + if content_type is None: + return queryset + + ct = determine_content_type(content_type) + if ct is None: raise ValueError(f'Invalid content type: {content_type}')