Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Django model mixin to force Django to validate (i.e. call `full_clean`) before `save`
class ValidateModelMixin(object):
"""Make :meth:`save` call :meth:`full_clean`.
.. warning:
This should be the left-most mixin/super-class of a model.
Do you think Django models ``save`` method will validate all fields
(i.e. call ``full_clean``) before saving or any time at all? Wrong!
I discovered this awful truth when I couldn't understand why
a model object with an email field (without `blank=True`) could be
saved with an empty string as email address.
More info:
* "Why doesn't django's model.save() call full clean?"
http://stackoverflow.com/questions/4441539/
* "Model docs imply that ModelForm will call Model.full_clean(),
but it won't."
https://code.djangoproject.com/ticket/13100
"""
def save(self, *args, **kwargs):
"""Call :meth:`full_clean` before saving."""
self.full_clean()
super(ValidateModelMixin, self).save(*args, **kwargs)
@MrKesn

This comment has been minimized.

Copy link

@MrKesn MrKesn commented Jan 28, 2015

Thank you! So easy and so useful.

@utkjad

This comment has been minimized.

Copy link

@utkjad utkjad commented Jun 2, 2015

So, if I do not define save() method in my Model Class , will this work?
I doubt that. One needs to write a save in Model Class

@dursk

This comment has been minimized.

Copy link

@dursk dursk commented Jun 16, 2015

This will work perfectly fine without defining a save method in your model class. You'll be inheriting this save method. Just be sure to write the inheritance chain in this order:

class MyMode(ValidateModelMixin, models.Model):
    ...
@court-jus

This comment has been minimized.

Copy link

@court-jus court-jus commented Aug 20, 2015

Be warned that this won't work for operations involving .update(), you should implement your constraint at the DB level

@kaidokert

This comment has been minimized.

Copy link

@kaidokert kaidokert commented Aug 23, 2015

I was looking at this as a real good model validation approach too, but indeed, query methods like update, select_for_update, bulk_create etc will all completely bypass this.

@gonzaloamadio

This comment has been minimized.

Copy link

@gonzaloamadio gonzaloamadio commented Dec 13, 2018

I was looking at this as a real good model validation approach too, but indeed, query methods like update, select_for_update, bulk_create etc will all completely bypass this.

Have you found an answer to this? On how to validate also in query methods like update, etc?
Is possible this validation?

Or whats the "final solution" for valid objects.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment