Conversation
IntegerFieldType/DecimalFieldType.get_model_field() never attached MinValueValidator/MaxValueValidator to the generated model field, and get_serializer_field() (added in #700) never passed min_value/max_value to the DRF field either - only get_form_field() enforced validation_minimum/ validation_maximum, the same underlying gap as #700 for range validation instead of required. Both get_model_field() implementations now append MinValueValidator/ MaxValueValidator (guarded by is not None) to the model field's validators, and both get_serializer_field() implementations pass min_value=field.validation_minimum, max_value=field.validation_maximum directly - DRF's IntegerField/DecimalField already no-op when either is None, so no extra guarding is needed there.
|
@claude /review and limit response to actionable issues. |
|
Claude finished @bctiemann's task in 1m 53s —— View job Review: Enforce integer/decimal min/max at model and REST layersThe fix is correct — all three enforcement layers (model 1.
|
- Only add "validators" to field_kwargs when non-empty in IntegerFieldType/DecimalFieldType.get_model_field(), so a caller-supplied validators kwarg isn't silently overwritten when neither validation_minimum nor validation_maximum is set. - Add exact-boundary assertions (validation_minimum/maximum themselves, not just values just inside/outside the range) to both full_clean() tests and the REST API test.
|
Addressed both in d51453d:
14/14 in the affected test classes. |
Closes: #715
Summary
Follow-up to #700, raised during that work:
IntegerFieldType/DecimalFieldType.get_model_field()never attachedMinValueValidator/MaxValueValidatorto the generated model field, and theirget_serializer_field()(added in #700) never passedmin_value/max_valueto the DRF field either — onlyget_form_field()enforcedvalidation_minimum/validation_maximum. Same underlying gap-shape as #700, just for range validation instead of required.Note: this PR targets the
700-required-fields-not-enforcedbranch, notmain— it builds directly on theget_serializer_field()methods #700/#714 introduces, which aren't onmainyet. Retarget tomainonce #714 merges.get_model_field()implementations now appendMinValueValidator/MaxValueValidator(guarded byis not None) to the model field'svalidators.get_serializer_field()implementations passmin_value=field.validation_minimum, max_value=field.validation_maximumdirectly — DRF'sIntegerField/DecimalFieldalready no-op when either isNone, so no extra guarding is needed on that side.Test plan
test_integer_field_min_max_enforced_by_full_clean/test_decimal_field_min_max_enforced_by_full_clean(new,test_field_types.py) — model-layerfull_clean()rejects out-of-range values, accepts in-range ones.IntegerDecimalMinMaxAPITest(new,test_api.py) — REST-layer:POSTabove/below the configured range returns 400 with per-field errors;POSTwithin range returns 201.full_clean()) and REST layers reject out-of-range values on both bounds, for both types.test_api,test_field_types,test_forms,test_views— 427 tests) — 4 pre-existing errors observed, matching the already-establishednetbox_branchingapp_label baseline, confirmed unrelated.ruff checkpasses on all changed files.