mirror of
https://github.com/inventree/InvenTree.git
synced 2025-08-07 20:32:12 +00:00
Improve back-end validation
This commit is contained in:
@@ -3403,7 +3403,30 @@ class Attachment(InvenTree.models.MetadataMixin, InvenTree.models.InvenTreeModel
|
|||||||
|
|
||||||
|
|
||||||
class InvenTreeCustomUserStateModel(models.Model):
|
class InvenTreeCustomUserStateModel(models.Model):
|
||||||
"""Custom model to extends any registered state with extra custom, user defined states."""
|
"""Custom model to extends any registered state with extra custom, user defined states.
|
||||||
|
|
||||||
|
Fields:
|
||||||
|
reference_status: Status set that is extended with this custom state
|
||||||
|
logical_key: State logical key that is equal to this custom state in business logic
|
||||||
|
key: Numerical value that will be saved in the models database
|
||||||
|
name: Name of the state (must be uppercase and a valid variable identifier)
|
||||||
|
label: Label that will be displayed in the frontend (human readable)
|
||||||
|
color: Color that will be displayed in the frontend
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
reference_status = models.CharField(
|
||||||
|
max_length=250,
|
||||||
|
verbose_name=_('Reference Status Set'),
|
||||||
|
help_text=_('Status set that is extended with this custom state'),
|
||||||
|
)
|
||||||
|
|
||||||
|
logical_key = models.IntegerField(
|
||||||
|
verbose_name=_('Logical Key'),
|
||||||
|
help_text=_(
|
||||||
|
'State logical key that is equal to this custom state in business logic'
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
key = models.IntegerField(
|
key = models.IntegerField(
|
||||||
verbose_name=_('Value'),
|
verbose_name=_('Value'),
|
||||||
@@ -3411,7 +3434,13 @@ class InvenTreeCustomUserStateModel(models.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
name = models.CharField(
|
name = models.CharField(
|
||||||
max_length=250, verbose_name=_('Name'), help_text=_('Name of the state')
|
max_length=250,
|
||||||
|
verbose_name=_('Name'),
|
||||||
|
help_text=_('Name of the state'),
|
||||||
|
validators=[
|
||||||
|
common.validators.validate_uppercase,
|
||||||
|
common.validators.validate_variable_string,
|
||||||
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
label = models.CharField(
|
label = models.CharField(
|
||||||
@@ -3428,13 +3457,6 @@ class InvenTreeCustomUserStateModel(models.Model):
|
|||||||
help_text=_('Color that will be displayed in the frontend'),
|
help_text=_('Color that will be displayed in the frontend'),
|
||||||
)
|
)
|
||||||
|
|
||||||
logical_key = models.IntegerField(
|
|
||||||
verbose_name=_('Logical Key'),
|
|
||||||
help_text=_(
|
|
||||||
'State logical key that is equal to this custom state in business logic'
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
model = models.ForeignKey(
|
model = models.ForeignKey(
|
||||||
ContentType,
|
ContentType,
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
@@ -3444,12 +3466,6 @@ class InvenTreeCustomUserStateModel(models.Model):
|
|||||||
help_text=_('Model this state is associated with'),
|
help_text=_('Model this state is associated with'),
|
||||||
)
|
)
|
||||||
|
|
||||||
reference_status = models.CharField(
|
|
||||||
max_length=250,
|
|
||||||
verbose_name=_('Reference Status Set'),
|
|
||||||
help_text=_('Status set that is extended with this custom state'),
|
|
||||||
)
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
"""Metaclass options for this mixin."""
|
"""Metaclass options for this mixin."""
|
||||||
|
|
||||||
@@ -3493,17 +3509,21 @@ class InvenTreeCustomUserStateModel(models.Model):
|
|||||||
get_custom_classes(include_custom=False),
|
get_custom_classes(include_custom=False),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(ref_set) == 0:
|
if len(ref_set) == 0:
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'reference_status': _('Reference status set not found')
|
'reference_status': _('Reference status set not found')
|
||||||
})
|
})
|
||||||
|
|
||||||
ref_set = ref_set[0]
|
ref_set = ref_set[0]
|
||||||
|
|
||||||
if self.key in ref_set.keys(): # noqa: SIM118
|
if self.key in ref_set.keys(): # noqa: SIM118
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'key': _(
|
'key': _(
|
||||||
'Key must be different from the logical keys of the reference status'
|
'Key must be different from the logical keys of the reference status'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.logical_key not in ref_set.keys(): # noqa: SIM118
|
if self.logical_key not in ref_set.keys(): # noqa: SIM118
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
'logical_key': _(
|
'logical_key': _(
|
||||||
|
@@ -335,6 +335,7 @@ class CustomStateSerializer(DataImportExportSerializerMixin, InvenTreeModelSeria
|
|||||||
]
|
]
|
||||||
|
|
||||||
model_name = serializers.CharField(read_only=True, source='model.name')
|
model_name = serializers.CharField(read_only=True, source='model.name')
|
||||||
|
|
||||||
reference_status = serializers.ChoiceField(
|
reference_status = serializers.ChoiceField(
|
||||||
choices=generic.states.custom.state_reference_mappings()
|
choices=generic.states.custom.state_reference_mappings()
|
||||||
)
|
)
|
||||||
|
@@ -113,3 +113,17 @@ def validate_icon(name: Union[str, None]):
|
|||||||
return
|
return
|
||||||
|
|
||||||
common.icons.validate_icon(name)
|
common.icons.validate_icon(name)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_uppercase(value: str):
|
||||||
|
"""Ensure that the provided value is uppercase."""
|
||||||
|
value = str(value)
|
||||||
|
|
||||||
|
if value != value.upper():
|
||||||
|
raise ValidationError(_('Value must be uppercase'))
|
||||||
|
|
||||||
|
|
||||||
|
def validate_variable_string(value: str):
|
||||||
|
"""The passed value must be a valid variable identifier string."""
|
||||||
|
if not re.match(r'^[a-zA-Z_][a-zA-Z0-9_]*$', value):
|
||||||
|
raise ValidationError(_('Value must be a valid variable identifier'))
|
||||||
|
Reference in New Issue
Block a user