2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-12-18 02:08:22 +00:00

Add ParameterTemplate model

- Data structure duplicated from PartParameterTemplate
This commit is contained in:
Oliver Walters
2025-10-28 11:12:09 +00:00
parent f2b531bfbb
commit 8bc131c93d
2 changed files with 246 additions and 0 deletions

View File

@@ -0,0 +1,97 @@
# Generated by Django 4.2.25 on 2025-10-28 11:11
import InvenTree.models
import InvenTree.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("common", "0039_emailthread_emailmessage"),
]
operations = [
migrations.CreateModel(
name="ParameterTemplate",
fields=[
(
"id",
models.AutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"metadata",
models.JSONField(
blank=True,
help_text="JSON metadata field, for use by external plugins",
null=True,
verbose_name="Plugin Metadata",
),
),
(
"name",
models.CharField(
help_text="Parameter Name",
max_length=100,
unique=True,
verbose_name="Name",
),
),
(
"units",
models.CharField(
blank=True,
help_text="Physical units for this parameter",
max_length=25,
validators=[InvenTree.validators.validate_physical_units],
verbose_name="Units",
),
),
(
"description",
models.CharField(
blank=True,
help_text="Parameter description",
max_length=250,
verbose_name="Description",
),
),
(
"checkbox",
models.BooleanField(
default=False,
help_text="Is this parameter a checkbox?",
verbose_name="Checkbox",
),
),
(
"choices",
models.CharField(
blank=True,
help_text="Valid choices for this parameter (comma-separated)",
max_length=5000,
verbose_name="Choices",
),
),
(
"selectionlist",
models.ForeignKey(
blank=True,
help_text="Selection list for this parameter",
null=True,
on_delete=django.db.models.deletion.SET_NULL,
related_name="templates",
to="common.selectionlist",
verbose_name="Selection List",
),
),
],
bases=(InvenTree.models.PluginValidationMixin, models.Model),
),
]

View File

@@ -53,6 +53,7 @@ import InvenTree.helpers
import InvenTree.models import InvenTree.models
import InvenTree.ready import InvenTree.ready
import InvenTree.tasks import InvenTree.tasks
import InvenTree.validators
import users.models import users.models
from common.setting.type import InvenTreeSettingsKeyType, SettingsKeyType from common.setting.type import InvenTreeSettingsKeyType, SettingsKeyType
from common.settings import get_global_setting, global_setting_overrides from common.settings import get_global_setting, global_setting_overrides
@@ -2362,6 +2363,154 @@ class SelectionListEntry(models.Model):
return self.label return self.label
class ParameterTemplate(
InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel
):
"""A ParameterTemplate provides a template for defining parameter values against various models.
This allow for assigning arbitrary data fields against existing models,
extending their functionality beyond the built-in fields.
Attributes:
name: The name (key) of the template
description: A description of the template
units: The units associated with the template (if applicable)
checkbox: Is this template a checkbox (boolean) type?
choices: Comma-separated list of choices (if applicable)
selectionlist: Optional link to a SelectionList for this template
"""
class Meta:
"""Metaclass options for the ParameterTemplate model."""
@staticmethod
def get_api_url() -> str:
"""Return the API URL associated with the ParameterTemplate model."""
return reverse('api-parameter-template-list')
def __str__(self):
"""Return a string representation of a ParameterTemplate instance."""
s = str(self.name)
if self.units:
s += f' ({self.units})'
return s
def clean(self):
"""Custom cleaning step for this model.
Checks:
- A 'checkbox' field cannot have 'choices' set
- A 'checkbox' field cannot have 'units' set
"""
super().clean()
# Check that checkbox parameters do not have units or choices
if self.checkbox:
if self.units:
raise ValidationError({
'units': _('Checkbox parameters cannot have units')
})
if self.choices:
raise ValidationError({
'choices': _('Checkbox parameters cannot have choices')
})
# Check that 'choices' are in fact valid
if self.choices is None:
self.choices = ''
else:
self.choices = str(self.choices).strip()
if self.choices:
choice_set = set()
for choice in self.choices.split(','):
choice = choice.strip()
# Ignore empty choices
if not choice:
continue
if choice in choice_set:
raise ValidationError({'choices': _('Choices must be unique')})
choice_set.add(choice)
def validate_unique(self, exclude=None):
"""Ensure that PartParameterTemplates cannot be created with the same name.
This test should be case-insensitive (which the unique caveat does not cover).
"""
super().validate_unique(exclude)
try:
others = ParameterTemplate.objects.filter(name__iexact=self.name).exclude(
pk=self.pk
)
if others.exists():
msg = _('Parameter template name must be unique')
raise ValidationError({'name': msg})
except ParameterTemplate.DoesNotExist:
pass
def get_choices(self):
"""Return a list of choices for this parameter template."""
if self.selectionlist:
return self.selectionlist.get_choices()
if not self.choices:
return []
return [x.strip() for x in self.choices.split(',') if x.strip()]
name = models.CharField(
max_length=100,
verbose_name=_('Name'),
help_text=_('Parameter Name'),
unique=True,
)
units = models.CharField(
max_length=25,
verbose_name=_('Units'),
help_text=_('Physical units for this parameter'),
blank=True,
validators=[InvenTree.validators.validate_physical_units],
)
description = models.CharField(
max_length=250,
verbose_name=_('Description'),
help_text=_('Parameter description'),
blank=True,
)
checkbox = models.BooleanField(
default=False,
verbose_name=_('Checkbox'),
help_text=_('Is this parameter a checkbox?'),
)
choices = models.CharField(
max_length=5000,
verbose_name=_('Choices'),
help_text=_('Valid choices for this parameter (comma-separated)'),
blank=True,
)
selectionlist = models.ForeignKey(
SelectionList,
blank=True,
null=True,
on_delete=models.SET_NULL,
related_name='templates',
verbose_name=_('Selection List'),
help_text=_('Selection list for this parameter'),
)
class BarcodeScanResult(InvenTree.models.InvenTreeModel): class BarcodeScanResult(InvenTree.models.InvenTreeModel):
"""Model for storing barcode scans results.""" """Model for storing barcode scans results."""