Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django IntegerRangeField Validation failing

I'm trying to implement the IntegerRangeField() for an age range field. Unfortunately the documentation doesn't say how to validate the upper and lower bounds.

I tried it from the model like so:

class SomeModel(models.Model):
    age_range = IntegerRangeField(default='(0,100)', blank=True, validators=[MinValueValidator(1), MaxValueValidator(100)])

The problem is, no matter what you put in the field, Django throws a ValidationError:

The value must be less than or equal to 100

Also if I put nothing in the field, it doesn't put the default range, and fails, complaining about an IntegrityError.

So, I tried doing this from the form object:

class SomeForm(forms.ModelForm):
    age_range = IntegerRangeField(validators=[MinValueValidator(1), MaxValueValidator(100)])

But that does nothing at all. Any figure I put in the fields saves. What am I doing wrong?

like image 555
onyeka Avatar asked Apr 05 '15 17:04

onyeka


1 Answers

The MinValueValidator and MaxValueValidator are for integers, so they are the incorrect validators to use here. Instead use the validators specifically for ranges: RangeMinValueValidator and RangeMaxValueValidator.

Both of those validators live in the module django.contrib.postgres.validators.

Here is a link to the validator source code.

Also, an IntegerRangeField is represented in Python as a psycopg2.extras.NumericRange object, so try using that instead of a string when you specify your default parameter in the model.

Note: The NumericRange object by default is inclusive of the lower bound and exclusive of the upper bound, so NumericRange(0, 100) would include 0 and not include 100. You probably want NumericRange(1, 101). You can also specify a bounds parameter in your NumericRange object to change the defaults for inclusion/exclusion, in lieu of changing the number values. See the NumericRange object documentation.

Example:

# models.py file
from django.contrib.postgres.validators import RangeMinValueValidator, RangeMaxValueValidator
from psycopg2.extras import NumericRange

class SomeModel(models.Model):
    age_range = IntegerRangeField(
        default=NumericRange(1, 101),
        blank=True,
        validators=[
            RangeMinValueValidator(1), 
            RangeMaxValueValidator(100)
        ]
    )
like image 145
Christian Abbott Avatar answered Sep 17 '22 15:09

Christian Abbott