6

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?

onyeka
  • 1,517
  • 13
  • 18
  • try this and tell me what happens: ``age_range = IntegerRangeField(lower=1, upper=100, bounds="[]")`` I got it from psycopg2 docs here http://initd.org/psycopg/docs/extras.html#psycopg2.extras.NumericRange – HassenPy Apr 05 '15 at 19:30
  • the django IntegerRangeField docs mentions that it inherits from the NumericRange field in psycopg2, and don't forget that those are PostgreSQL specific fields, make sure you are using a PostgreSQL db. – HassenPy Apr 05 '15 at 19:32
  • @HassenPy That was actually the first thing I tried in the model. Didn't work. Django wouldn't even migrate, said they were unexpected keywords. – onyeka Apr 05 '15 at 21:08
  • personally, I wouldn't use a badly documented feature that practically lacks resources on how to implement, try creating a custom field of your own, this might interest you thou http://stackoverflow.com/questions/849142/how-to-limit-the-maximum-value-of-a-numeric-field-in-a-django-model – HassenPy Apr 05 '15 at 22:08

1 Answers1

9

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)
        ]
    )
Christian Abbott
  • 6,497
  • 2
  • 21
  • 26
  • This worked! I looked through all the contrib.postgres files but must have missed this. Thanks. The NumericRange note was helpful too, though it seemed my previous method also worked. – onyeka Apr 06 '15 at 13:52