Using django fields validation for external values

273 views Asked by At

I have model with one field(this is synthetic example):

model Tank:
      oxygen = models.PositiveSmallIntegerField(
          _("Oxygen %"),
          help_text="%",
          default=21,
          validators=[MinValueValidator(21.0), MaxValueValidator(50.0)],
          null=True,
      )

And I parse some files with data. I want to validate input data before write it model instance. Something like this

oxygen = get_raw_data()
Tank.oxygen.validate(oxygen) # this is wrong I know :)
# if value is valid do something
# else do something

What should I write instead of Tank.oxygen.validate(oxygen)? I can duplicate validation logic or validate data when save model instance, but maybe somebody know better solution.

2

There are 2 answers

3
Daniel Roseman On

You need to actually create an instance with the data, then call full_clean() on it:

my_tank = Tank(oxygen=oxygen)
my_tank.full_clean()
0
Armando Alvarado On

If you only want to validate one field, then I suggest you use a form.Field class to do it:

from django import forms
from django.core.exceptions import ValidationError

oxygen_field = forms.IntegerField(required=True, min_value=21, max_value=50)

def is_oxygen_valid(value):
    try:
        oxygen_field.clean(value)
    except ValidationError:
        return False
    else:
        return True

Testing:

>>> is_oxygen_valid(None)
False
>>> is_oxygen_valid(11)
False
>>> is_oxygen_valid(55)
False
>>> is_oxygen_valid('hello')
False
>>> is_oxygen_valid(list())
False
>>> is_oxygen_valid(45)
True

I'm assuming that you are going to be validating the oxygen field first, and then deciding what to do depending on the result. You could adapt this to any other field you need. Just find the appropriate FormField class, and any Validators you might need, and use that instead.