Ajay Kumar
Ajay Kumar

Reputation: 1655

Django model validator not working on create

I have model with a field validator

from django.db import models
from django.core.validators import MinValueValidator, MaxValueValidator

 class MyModel(model.Model):
     name = models.CharField()
     size = models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(10)])

The validator is working well in the django admin panel ,while I try to enter the value more than 10, it's showing me the error message 'Ensure this value is less than or equal to 10' and does not allow to save.

But, when I try in the django shell, the validator is not working, it allows to save the record, I don't know why is the validator not throwing error message here.

>>>form app.models import MyModel
>>>MyModel.objects.create(name="Some Name", size=15)
<MyModel: Some Name>

Can you please suggest me if anything I missed or any mistake i did here. Kindly help me to solve this problem, it will be very greatfull for me, Thanks in advance.

Upvotes: 45

Views: 18901

Answers (8)

It is worth mentioning that model field validators

like validate_color in here:

bg_color = models.CharField(
    max_length=50, default="f0f2f5", validators=[validate_color]
)

work with restf_ramework (drf) Serializer class either.

https://github.com/encode/django-rest-framework/blob/master/rest_framework/serializers.py

so validators run when you call is_valid on ModelForm (from django) or is_valid on Serializer (from rest_framework).

Upvotes: 0

Ali Amigh
Ali Amigh

Reputation: 1

You can not run validator in creating you must run validation in instance if not exception occurred you must save it

Upvotes: -1

dehidehidehi
dehidehidehi

Reputation: 117

You can add this to your model and call it in save().

    def save(self, *args, **kwargs):
        self.run_validators()
        super().save(*args, **kwargs)

    def run_validators(self) -> None:
        for field_name, field_value in model_to_dict(self).items():
            model_field = getattr(UserSearchHistory, field_name)
            field = getattr(model_field, 'field', object())
            validators = getattr(field, 'validators', list())
            for validator_func in validators:
                if field_value is not None:
                    validator_func(field_value)

Upvotes: 0

Abhishek Sahu
Abhishek Sahu

Reputation: 46

I ran into the same issue. So the validators only work when you are using Forms and Model Form to fill it.

However, by creating in shell, you probably wanted to test the validators before going live. So here is the additional piece of code to help in validating the validators.

>>>form app.models import MyModel
>>>MyModel.size.field.run_validators(value=<undesirable value>)

Upvotes: 0

powlo
powlo

Reputation: 2688

From django documentation:

Note that validators will not be run automatically when you save a model, but if you are using a ModelForm, it will run your validators on any fields that are included in your form.

https://docs.djangoproject.com/en/3.1/ref/validators/#how-validators-are-run

Upvotes: 0

VStoykov
VStoykov

Reputation: 1740

Django validation is mostly application level validation and not validation at DB level. Also Model validation is not run automatically on save/create of the model. If you want to validate your values at certain time in your code then you need to do it manually.

For example:

from django.core.exceptions import ValidationError
form app.models import MyModel

instance = MyModel(name="Some Name", size=15)
try:
    instance.full_clean()
except ValidationError:
    # Do something when validation is not passing
else:
    # Validation is ok we will save the instance
    instance.save()

More info you can see at django's documentation https://docs.djangoproject.com/en/1.10/ref/models/instances/#validating-objects

In administration it works automatically because all model forms (ModelForm) will run model validation process alongside form validation.

If you need to validate data because it is coming from untrusted source (user input) you need to use ModelForms and save the model only when the form is valid.

Upvotes: 49

Ibrahim Tayseer
Ibrahim Tayseer

Reputation: 566

Validators work only with the Forms and model forms. Can't be used with the model definition because it runs at the app side not the DB side.

Upvotes: 0

sunny
sunny

Reputation: 748

The validator only works when you are using models in a ModelForm.

https://docs.djangoproject.com/en/dev/ref/validators/#how-validators-are-run

You can perform model validation by overidding clean() and full_clean() methods

Upvotes: 12

Related Questions