2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-05-02 05:26:45 +00:00

Settings validation enhancements (#8351)

* Enforce lower case for model name checks

* Enhance settings validation

- Add support for "float" settings type
- Improve validation code and error handling
This commit is contained in:
Oliver 2024-10-24 13:12:39 +11:00 committed by GitHub
parent fb17dcce9a
commit 556ff4f15b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 63 additions and 3 deletions

View File

@ -826,6 +826,9 @@ class BaseInvenTreeSetting(models.Model):
elif self.is_bool(): elif self.is_bool():
self.value = self.as_bool() self.value = self.as_bool()
elif self.is_float():
self.value = self.as_float()
validator = self.__class__.get_setting_validator( validator = self.__class__.get_setting_validator(
self.key, **self.get_filters_for_instance() self.key, **self.get_filters_for_instance()
) )
@ -862,6 +865,14 @@ class BaseInvenTreeSetting(models.Model):
except (ValueError, TypeError): except (ValueError, TypeError):
raise ValidationError({'value': _('Value must be an integer value')}) raise ValidationError({'value': _('Value must be an integer value')})
# Floating point validator
if validator is float:
try:
# Coerce into a floating point value
value = float(value)
except (ValueError, TypeError):
raise ValidationError({'value': _('Value must be a valid number')})
# If a list of validators is supplied, iterate through each one # If a list of validators is supplied, iterate through each one
if type(validator) in [list, tuple]: if type(validator) in [list, tuple]:
for v in validator: for v in validator:
@ -873,10 +884,18 @@ class BaseInvenTreeSetting(models.Model):
if self.is_bool(): if self.is_bool():
value = self.as_bool() value = self.as_bool()
if self.is_int(): elif self.is_int():
value = self.as_int() value = self.as_int()
elif self.is_float():
value = self.as_float()
try:
validator(value) validator(value)
except ValidationError as e:
raise e
except Exception:
raise ValidationError({'value': _('Invalid value')})
def validate_unique(self, exclude=None): def validate_unique(self, exclude=None):
"""Ensure that the key:value pair is unique. In addition to the base validators, this ensures that the 'key' is unique, using a case-insensitive comparison. """Ensure that the key:value pair is unique. In addition to the base validators, this ensures that the 'key' is unique, using a case-insensitive comparison.
@ -970,6 +989,9 @@ class BaseInvenTreeSetting(models.Model):
if not model_name: if not model_name:
return None return None
# Enforce lower-case model name
model_name = str(model_name).strip().lower()
try: try:
(app, mdl) = model_name.strip().split('.') (app, mdl) = model_name.strip().split('.')
except ValueError: except ValueError:
@ -1069,6 +1091,39 @@ class BaseInvenTreeSetting(models.Model):
return False return False
def is_float(self):
"""Check if the setting is required to be a float value."""
validator = self.__class__.get_setting_validator(
self.key, **self.get_filters_for_instance()
)
return self.__class__.validator_is_float(validator)
@classmethod
def validator_is_float(cls, validator):
"""Return if validator is for float."""
if validator == float:
return True
if type(validator) in [list, tuple]:
for v in validator:
if v == float:
return True
return False
def as_float(self):
"""Return the value of this setting converted to a float value.
If an error occurs, return the default value
"""
try:
value = float(self.value)
except (ValueError, TypeError):
value = self.default_value
return value
def is_int(self): def is_int(self):
"""Check if the setting is required to be an integer value.""" """Check if the setting is required to be an integer value."""
validator = self.__class__.get_setting_validator( validator = self.__class__.get_setting_validator(

View File

@ -49,6 +49,9 @@
*/ */
function getModelRenderer(model) { function getModelRenderer(model) {
// Ensure correct formatting of provided model name
model = model.toString().toLowerCase();
// Find a custom renderer // Find a custom renderer
switch (model) { switch (model) {
case 'company': case 'company':

View File

@ -108,7 +108,9 @@ export function RenderInstance(props: RenderInstanceProps): ReactNode {
return <UnknownRenderer model={props.model} />; return <UnknownRenderer model={props.model} />;
} }
const RenderComponent = RendererLookup[props.model]; const model_name = props.model.toString().toLowerCase() as ModelType;
const RenderComponent = RendererLookup[model_name];
if (!RenderComponent) { if (!RenderComponent) {
console.error(`RenderInstance: No renderer for model ${props.model}`); console.error(`RenderInstance: No renderer for model ${props.model}`);