Skip to content

Instantly share code, notes, and snippets.

@glarrain
Created April 23, 2013 23:18
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save glarrain/5448253 to your computer and use it in GitHub Desktop.
Save glarrain/5448253 to your computer and use it in GitHub Desktop.
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
Copy link

MrKesn commented Jan 28, 2015

Thank you! So easy and so useful.

@utkjad
Copy link

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
Copy link

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
Copy link

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

@kaidokert
Copy link

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
Copy link

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