Opened 8 months ago

Closed 8 months ago

#35433 closed Bug (wontfix)

NumberInput min_value attr overridden by IntegerField.widget_attrs

Reported by: mitch99 Owned by: nobody
Component: Forms Version: 5.0
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Given this:

widgets = {
   "weight": forms.NumberInput(attrs={'type':'range', 'step': '1', 'min': '1', 'max': '5'),
}

I expect the min value on the range input to be 1, but it's actually 0:

<input type="range" name="form-2-weight" value="3" step="1" min="0" max="5" aria-describedby="id_form-2-weight_helptext" id="id_form-2-weight">

Change History (7)

comment:1 by Sarah Boyce, 8 months ago

Resolution: needsinfo
Status: newclosed

This is missing information to determine whether this is a bug or not, I need to see the how the form is defined and how the field weight is defined on the model.

comment:2 by mitch99, 8 months ago

Please see below:

class ContentProfileDefinitionForm(forms.ModelForm):
    class Meta:
        model = ContentProfileDefinition
        fields = ["other", "weight"]
        widgets = {
            "weight": forms.NumberInput(
                attrs={
                    "type": "range",
                    "step": "1",
                    "min": "1",
                    "max": "5",
                }
            ),
        }
        validators = {
            "weight": [
                MinValueValidator(1),
                MaxValueValidator(5),
            ]
        }
class ContentProfileDefinition(models.Model):
    other = models.ForeignKey("Other", on_delete=models.CASCADE)
    weight = models.PositiveSmallIntegerField(
        default=1,
        help_text="Weight",
        validators=[
            MinValueValidator(1),
            MaxValueValidator(5),
        ],
    )
Last edited 8 months ago by mitch99 (previous) (diff)

comment:3 by mitch99, 8 months ago

Resolution: needsinfo
Status: closednew

Unable to reopen so recreated at #35435

Version 0, edited 8 months ago by mitch99 (next)

comment:4 by mitch99, 8 months ago

Strangely it's not an off-by-one. It seems the min value is ignored and always set to 0.

comment:5 by Tim Graham, 8 months ago

Easy pickings: unset
Summary: NumberInput off-by-one on min value for type rangeNumberInput min_value attr overridden by IntegerField.widget_attrs

The root cause is that Field.__init__() overrides a widget's attrs with Field.widget_attrs which includes min_value=0 from PositiveIntegerField.formfield().

I'm not sure if we should change the behavior. The most appropriate fix for your use case might be to subclass PositiveIntegerField and override formfield() to set min_value=1.

comment:6 by David Sanders, 8 months ago

Yup what Tim said: There will be people relying on this existing behaviour 👍

Another way to get min="1" is to use django-widget-tweaks: https://github.com/jazzband/django-widget-tweaks I just tested it out and it works 👍

comment:7 by mitch99, 8 months ago

Resolution: wontfix
Status: newclosed

OK thanks I'll try these approaches.

Note: See TracTickets for help on using tickets.
Back to Top