Merge pull request 'Fix min/max value validation in configured form' (#322) from 286-simple-form-issues into main
All checks were successful
Build and Deploy Staging / build (push) Successful in 39s
Tests / test (push) Successful in 28s
Build and Deploy Staging / deploy (push) Successful in 7s

Reviewed-on: #322
This commit is contained in:
Tobias Brunner 2025-12-05 08:38:14 +00:00
commit d69b46ecfd
2 changed files with 59 additions and 4 deletions

View file

@ -371,11 +371,13 @@ class CustomFormMixin(FormGeneratorMixin):
validators = []
if min_val is not None:
validators.append(MinValueValidator(min_val))
field.widget.attrs["min"] = min_val
with suppress(ValueError):
validators.append(MinValueValidator(int(min_val)))
field.widget.attrs["min"] = min_val
if max_val is not None:
validators.append(MaxValueValidator(max_val))
field.widget.attrs["max"] = max_val
with suppress(ValueError):
validators.append(MaxValueValidator(int(max_val)))
field.widget.attrs["max"] = max_val
if validators:
field.validators.extend(validators)

View file

@ -1055,6 +1055,59 @@ def test_empty_values_dont_override_default_configs():
assert name_field.required is False # Was overridden by explicit False
def test_number_field_validates_min_max_values():
class TestModel(models.Model):
name = models.CharField(max_length=100)
port = models.IntegerField()
class Meta:
app_label = "test"
form_config = {
"fieldsets": [
{
"title": "General",
"fields": [
{
"type": "text",
"label": "Name",
"controlplane_field_mapping": "name",
"required": True,
},
{
"type": "number",
"label": "Port",
"controlplane_field_mapping": "port",
"required": True,
"min_value": "1",
"max_value": "65535",
},
],
}
]
}
form_class = generate_custom_form_class(form_config, TestModel)
# Test value below minimum fails validation
form = form_class(data={"name": "test-service", "port": 0})
form.fields["context"].required = False
assert not form.is_valid()
assert "port" in form.errors
# Test value above maximum fails validation
form = form_class(data={"name": "test-service", "port": 65536})
form.fields["context"].required = False
assert not form.is_valid()
assert "port" in form.errors
# Test valid value passes validation
form = form_class(data={"name": "test-service", "port": 8080})
form.fields["context"].required = False
assert form.is_valid(), f"Form should be valid but has errors: {form.errors}"
def test_number_field_with_addon_text_roundtrip():
class TestModel(models.Model):
name = models.CharField(max_length=100)