From 86cc826671e87838150ae26766a77fa183c12fe4 Mon Sep 17 00:00:00 2001 From: Oliver Walters Date: Mon, 10 Nov 2025 10:37:03 +0000 Subject: [PATCH] API updates - Fix options for model_type - Add API filters --- src/backend/InvenTree/common/api.py | 14 +++++++++++++- src/backend/InvenTree/common/models.py | 14 +++----------- src/backend/InvenTree/common/serializers.py | 4 ++-- src/backend/InvenTree/common/validators.py | 8 ++++++++ src/backend/InvenTree/part/models.py | 1 + 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/backend/InvenTree/common/api.py b/src/backend/InvenTree/common/api.py index 3736c67b00..2f1f1bb6d7 100644 --- a/src/backend/InvenTree/common/api.py +++ b/src/backend/InvenTree/common/api.py @@ -772,7 +772,7 @@ class ParameterTemplateFilter(FilterSet): """Metaclass options.""" model = common.models.ParameterTemplate - fields = ['name', 'units', 'checkbox'] + fields = ['model_type', 'name', 'units', 'checkbox'] has_choices = rest_filters.BooleanFilter( method='filter_has_choices', label='Has Choice' @@ -794,6 +794,18 @@ class ParameterTemplateFilter(FilterSet): return queryset.filter(Q(units=None) | Q(units='')).distinct() + for_model = rest_filters.CharFilter(method='filter_for_model', label='For Model') + + def filter_for_model(self, queryset, name, value): + """Filter queryset to include only ParameterTemplates which apply to the given model. + + Note that this varies from the 'model_type' filter, in that ParameterTemplates + with a blank 'model_type' are considered to apply to all models. + """ + return queryset.filter( + Q(model_type__iexact=value) | Q(model_type__isnull=True) | Q(model_type='') + ).distinct() + class ParameterTemplateMixin: """Mixin class for ParameterTemplate views.""" diff --git a/src/backend/InvenTree/common/models.py b/src/backend/InvenTree/common/models.py index a9162f2a92..779fa6e5a8 100644 --- a/src/backend/InvenTree/common/models.py +++ b/src/backend/InvenTree/common/models.py @@ -72,21 +72,14 @@ class RenderMeta(enums.ChoicesMeta): """Metaclass for rendering choices.""" choice_fnc = None - allow_blank: bool = False - blank_label: str = '------' @property def choices(self): """Return a list of choices for the enum class.""" fnc = getattr(self, 'choice_fnc', None) if fnc: - options = fnc() - options = [] - - if self.allow_blank: - options.insert(0, ('', self.blank_label)) - - return options + return fnc() + return [] class RenderChoices(models.TextChoices, metaclass=RenderMeta): # type: ignore @@ -2395,8 +2388,7 @@ class ParameterTemplate( class ModelChoices(RenderChoices): """Model choices for parameter templates.""" - allow_blank = True - choice_fnc = common.validators.parameter_model_options + choice_fnc = common.validators.parameter_template_model_options @staticmethod def get_api_url() -> str: diff --git a/src/backend/InvenTree/common/serializers.py b/src/backend/InvenTree/common/serializers.py index b7461cfb77..fd85fa287e 100644 --- a/src/backend/InvenTree/common/serializers.py +++ b/src/backend/InvenTree/common/serializers.py @@ -724,13 +724,13 @@ class ParameterTemplateSerializer( if len(self.fields['model_type'].choices) == 0: self.fields[ 'model_type' - ].choices = common.validators.attachment_model_options() + ].choices = common.validators.parameter_template_model_options() # Note: The choices are overridden at run-time on class initialization model_type = serializers.ChoiceField( label=_('Model Type'), default='', - choices=common.validators.attachment_model_options(), + choices=common.validators.parameter_template_model_options(), required=False, allow_blank=True, allow_null=True, diff --git a/src/backend/InvenTree/common/validators.py b/src/backend/InvenTree/common/validators.py index dcdcd693d0..b49f36b1b1 100644 --- a/src/backend/InvenTree/common/validators.py +++ b/src/backend/InvenTree/common/validators.py @@ -29,6 +29,14 @@ def parameter_model_options(): ] +def parameter_template_model_options(): + """Return a list of options for models which support parameter templates. + + Note: This includes a blank option at the start, since ParameterTemplate.model_type may be blank. + """ + return [('', _('Any model type')), *parameter_model_options()] + + def validate_parameter_model_type(value: str): """Ensure that the provided parameter model is valid.""" model_names = [el[0] for el in parameter_model_options()] diff --git a/src/backend/InvenTree/part/models.py b/src/backend/InvenTree/part/models.py index ab6d5e7944..ea10967457 100644 --- a/src/backend/InvenTree/part/models.py +++ b/src/backend/InvenTree/part/models.py @@ -410,6 +410,7 @@ class PartReportContext(report.mixins.BaseReportContext): @cleanup.ignore class Part( InvenTree.models.PluginValidationMixin, + InvenTree.models.InvenTreeParameterMixin, InvenTree.models.InvenTreeAttachmentMixin, InvenTree.models.InvenTreeBarcodeMixin, InvenTree.models.InvenTreeNotesMixin,