Reputation: 2692
I'm attempting to make a custom type in Django:
from django.db.models import DecimalField
from django.core import validators
from django.utils.functional import cached_property
class MinOneHundredDecimalField(DecimalField):
@cached_property
def validators(self):
return super().validators + [
validators.MinValueValidator(100, "Minimum value is 100"),
]
And I use this in my model:
class MyModel(BaseModel):
amount = MinOneHundredDecimalField(
decimal_places=2,
max_digits=6,
)
However when testing, I'm able to set amount to a value less than 100:
def test_min_val(self):
my_model = MyModel(amount=50)
my_model.save()
self.assertNotEqual(my_model.amount, 50, "Message here")
I also tried adding the validator directly in the model, but I get the same result:
amount = MinOneHundredDecimalField(
decimal_places=2,
max_digits=6,
validators=[MinValueValidator(100.0, "Minimum value is 0")]
)
Any ideas why this validator isn't working? Ty!
Upvotes: 1
Views: 80
Reputation: 88499
You need to call the full_clean()
--(Django doc) method too... So, you have to change the test cases to something like,
from django.core import exceptions
class FooTest(TestCase):
def test_min_val(self):
my_model = MyModel(amount=50)
with self.assertRaises(exceptions.ValidationError) as context:
my_model.full_clean()
self.assertIn('Minimum value is 100', context.exception.message_dict['amount'])
Upvotes: 3
Reputation: 10327
You should check the documentation on validators, it states
Note that validators will not be run automatically when you save a model
In the section on validating objects it says there are three steps involved in validating a model and they are performed when you call a model’s full_clean()
method.
At the moment you are only calling save()
which will not trigger the field validation.
You can override the save()
method in your model to call full_clean()
but be careful doing this if you later use your model linked to a model form, when validation will be performed automatically.
Upvotes: 1