Note that full_clean() will NOT be called automatically when you call your model's save() method. You'll need to call it manually if you want to run model validation outside of a ModelForm. (This is for backwards compatibility.)
Creating objects To create an object, instantiate it using keyword arguments to the model class, then call save() to save it to the database. This performs an INSERT SQL statement behind the scenes. Django doesn't hit the database until you explicitly call save() . The save() method has no return value.
form. save() purpose is to save related model to database, you are right. You're also right about set_password , for more info just read the docs. Django knows about model and all it's data, due to instance it's holding (in your case user ).
Model MethodsDjango's Model class comes with many built-in methods. We have already used some of them— save() , delete() , __str__() and others. Where manager methods add table-level functionality to Django's models, model methods add row-level functions that act on individual instances of the model.
AFAIK, this is because of backwards compatibility. There are also problems with ModelForms with excluded fields, models with default values, pre_save() signals, etc.
Sources you might be intrested in:
Because of the compatibility considering, the auto clean on save is not enabled in django kernel.
If we are starting a new project and want the default save
method on Model could clean automatically, we can use the following signal to do clean before every model was saved.
from django.dispatch import receiver
from django.db.models.signals import pre_save, post_save
@receiver(pre_save)
def pre_save_handler(sender, instance, *args, **kwargs):
instance.full_clean()
The simplest way to call the full_clean
method is just to override the save
method in your model:
class YourModel(models.Model):
...
def save(self, *args, **kwargs):
self.full_clean()
return super(YourModel, self).save(*args, **kwargs)
Instead of inserting a piece of code that declares a receiver, we can use an app as INSTALLED_APPS
section in settings.py
INSTALLED_APPS = [
# ...
'django_fullclean',
# your apps here,
]
Before that, you may need to install django-fullclean
using PyPI:
pip install django-fullclean
Commenting on @Alfred Huang's answer and coments on it. One might lock the pre_save hook down to an app by defining a list of classes in the current module (models.py) and checking against it in the pre_save hook:
CUSTOM_CLASSES = [obj for name, obj in
inspect.getmembers(sys.modules[__name__])
if inspect.isclass(obj)]
@receiver(pre_save)
def pre_save_handler(sender, instance, **kwargs):
if type(instance) in CUSTOM_CLASSES:
instance.full_clean()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With