Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use full_clean() for data validation before saving in Django 1.5 gracefully?

I think Django's model validation is a little inconvenient for those models that don't use built-in ModelForm, though not knowing why.

Firstly, full_clean() needs called manually.

Note that full_clean() will not be called automatically when you call your model’s save() method, nor as a result of ModelForm validation.In the case of ModelForm validation, Model.clean_fields(), Model.clean(), and Model.validate_unique() are all called individually.You’ll need to call full_clean manually when you want to run one-step model validation for your own manually created models.

Secondly, validators are used in built-in ModelForm.

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.

There are great demands when you need to do data validation before saving data into databases. And obviously I'd prefer to make it in model, rather than views. So, are there any good ideas to implement this gracefully in Django 1.5?

like image 781
ray6080 Avatar asked Mar 23 '14 04:03

ray6080


People also ask

What does Full_clean () do in Django?

The first step full_clean() performs is to clean each individual field. Changed in Django 4.1: The validate_constraints argument was added.

Does Django save call clean?

save() calls the clean. This way the integrity is enforced both from forms and from other calling code, the command line, and tests. Without this, there is (AFAICT) no way to write a test that ensures that a model has a FK relation to a specifically chosen (not default) other model.

How does Django validate data?

Django forms submit only if it contains CSRF tokens. It uses uses a clean and easy approach to validate data. The is_valid() method is used to perform validation for each field of the form, it is defined in Django Form class. It returns True if data is valid and place all data into a cleaned_data attribute.


1 Answers

Even though the idea of enforcing validation on Model level seems right, Django does not do this by default for various reasons. Except for some backward-compatibility problems, the authors probably don't want to support this because they fear this could create a false feeling of safety when in fact your data are not guaranteed to be always validated. Some ORM methods (e.g. bulk_create or update) don't call save() and thus are unable to validate your models. In other words, it is hard to guarantee the validation, thus they've decided not to pretend it.

If you need this for multiple models, you can create a simple mixin that overrides the save() method and calls full_clean() before super. Do note that this might cause the validation to be run twice in some cases, like when using ModelForm. It might not be that of an issue though if your validation routines are side-effect free and cheap to run.

For more info, please see these answers:

  • https://stackoverflow.com/a/4441740/2263517
  • https://stackoverflow.com/a/12945692/2263517
  • https://stackoverflow.com/a/13039057/2263517
like image 147
knaperek Avatar answered Oct 06 '22 19:10

knaperek