[Django]-Django model.full_clean() allows invalid value for IntegerField

5👍

the reason of this behavior is commented in clean_fields method :

    def clean_fields(self, exclude=None):
    """
    Cleans all fields and raises a ValidationError containing message_dict
    of all validation errors if any occur.
    """
    if exclude is None:
        exclude = []

    errors = {}
    for f in self._meta.fields:
        if f.name in exclude:
            continue
        # Skip validation for empty fields with blank=True. The developer
        # is responsible for making sure they have a valid value.
        raw_value = getattr(self, f.attname)
        if f.blank and raw_value in f.empty_values:
            continue
        try:
            setattr(self, f.attname, f.clean(raw_value, self))
        except ValidationError as e:
            errors[f.name] = e.error_list

    if errors:
        raise ValidationError(errors)

2👍

You’re getting this behavior because you have blank=True. I agree with you that the behavior you’re seeing is strange – it’s a symptom of the fact that in Django model validation is tied up quite tightly with form validation, even though in principle they can be separate.

Assuming that you actually want blank=True and null=True, I wouldn’t worry about this. Forms will do the right thing (convert the empty string in a form to a NULL value in the database), and the model and database won’t actually let you save the invalid value. The only issue is that if you have data entry that doesn’t involve Django forms, the error will get thrown at save() time rather than at full_clean() time.

Of course, if you don’t want to allow NULL values for the field, just set blank=False, null=False and full_clean() will complain about the empty string just like you expect.

0👍

Well that is because you allowed your field to be blank (and also null).
so it is okay and it is valid.

If you don’t want it to be that way, just remove the blank=True option or change it to blank=False

Leave a comment