The Django docs only list examples for overriding save()
and delete()
. However, I'd like to define some extra processing for my models only when they are created. For anyone familiar with Rails, it would be the equivalent to creating a :before_create
filter. Is this possible?

- 9,017
- 2
- 24
- 47

- 4,464
- 8
- 30
- 35
7 Answers
Overriding __init__()
would cause code to be executed whenever the python representation of object is instantiated. I don't know rails, but a :before_created
filter sounds to me like it's code to be executed when the object is created in the database. If you want to execute code when a new object is created in the database, you should override save()
, checking if the object has a pk
attribute or not. The code would look something like this:
def save(self, *args, **kwargs):
if not self.pk:
# This code only happens if the objects is
# not in the database yet. Otherwise it would
# have pk
super(MyModel, self).save(*args, **kwargs)
-
9I've actually found a solution using signals: http://docs.djangoproject.com/en/dev/topics/signals/ (the pre_save signal, specifically). However, this seems to be a much more pragmatic solution. Thanks a bunch. – ground5hark Feb 24 '10 at 04:16
-
nice hack. I'd still prefer to override the create method as I'd like to add a logging.info call after creation of a new object. Calling it before and you have chance of that the the call to the parent method fail... – philgo20 Mar 25 '10 at 16:34
-
4I assume you mean overriding the manager method `create`? That's an interesting solution, but it wouldn't work in cases when the object is being created using `Object(**kwargs).save()` or any other variation on that. – Zach Mar 25 '10 at 17:07
-
5I don't think it's a hack. It's one of the official solutions. – skywalker Mar 07 '16 at 11:53
-
You can override the create method with a custom manager or add a classmethod on the model class. https://docs.djangoproject.com/en/1.10/ref/models/instances/#creating-objects – Ryan Allen Sep 01 '16 at 14:56
-
7Shouldn't it be `super(MyModel, self).save(*args, **kwargs)` ? – Mark Chackerian Jun 14 '17 at 17:22
-
@ground5hark you can have it both *a method* **and** *using signals*, I posted below the "have the cake and eat it too" solution because this is the first thing people see when googling how to do this :) cheers! – NeuronQ Aug 11 '17 at 14:42
-
12Maybe checking for `self.pk` is not the best option to check if the object is newly being created or just updating. Sometimes you provide object id in creation time (a customized non-database generated value like `KSUID`), and it'll cause this clause never to execute... There is `self._state.adding` value to make sure if it's saving for the first time or just updating, which helps in those cases. – Shahin Jun 19 '18 at 14:52
-
Thanks, Its a great solution with a single if condition... Good one@Zach. – Raviteja Jul 03 '20 at 16:57
To answer the question literally, the create
method in a model's manager is a standard way to create new objects in Django. To override, do something like
from django.db import models
class MyModelManager(models.Manager):
def create(self, **obj_data):
# Do some extra stuff here on the submitted data before saving...
# For example...
obj_data['my_field'] = my_computed_value(obj_data['my_other_field'])
# Now call the super method which does the actual creation
return super().create(**obj_data) # Python 3 syntax!!
class MyModel(models.model):
# An example model
my_field = models.CharField(max_length=250)
my_other_field = models.CharField(max_length=250)
objects = MyModelManager()
In this example, I'm overriding the Manager's method create
method to do some extra processing before the instance is actually created.
NOTE: Code like
my_new_instance = MyModel.objects.create(my_field='my_field value')
will execute this modified create
method, but code like
my_new_unsaved_instance = MyModel(my_field='my_field value')
will not.

- 21,866
- 6
- 108
- 99
-
I believe you have to call `super(MyModelManager, self).create(**obj_data)` instead of only `super().create(**obj_data)`. Other than that, this is a brilliant solution – Ricardo Vilaça Apr 22 '21 at 17:01
-
4
-
3I think this is the best solution after the "save" overload. The logic of signals is harder to follow, and does not fit the neat class-based solution of Django models. I always prefer overloading model methods or using Managers, instead of signals. – disconnectionist Aug 25 '21 at 07:18
This is old, has an accepted answer that works (Zach's), and a more idiomatic one too (Michael Bylstra's), but since it's still the first result on Google most people see, I think we need a more best-practices modern-django style answer here:
from django.db.models.signals import post_save
class MyModel(models.Model):
# ...
@classmethod
def post_create(cls, sender, instance, created, *args, **kwargs):
if not created:
return
# ...what needs to happen on create
post_save.connect(MyModel.post_create, sender=MyModel)
The point is this:
- use signals (read more here in the official docs)
- use a method for nice namespacing (if it makes sense) ...and I marked it as
@classmethod
instead of@staticmethod
because most likely you'll end up needing to refer static class members in the code
Even cleaner would be if core Django would have an actual post_create
signal. (Imho if you need to pass a boolean arg to change behavior of a method, that should be 2 methods.)

- 7,527
- 9
- 42
- 60
-
1Woudn't `post_init` be more appropriate? I'm new to signals, but I'd think that the way you set it up, the method is called on every `save()`, so updates would call this, too. – Matt McCarthy Jun 09 '21 at 01:00
-
1Even though this is clean and I like it, please note that in Django docs it's stated: "it’s recommended to avoid the application’s root module and its models module to minimize side-effects of importing code". This can basically easily generate circular imports (it did in my case). – Kurt Bourbaki Feb 10 '22 at 13:07
-
@KurtBourbaki thanks for noticing that. please suggest a better place to put such code, preferably the simplest such place – NeuronQ Feb 14 '22 at 09:48
-
@NeuronQ I defined `post_create()` as a function inside the `signals.py` module, as recommended by Django docs. This allowed me to avoid circular imports. Unfortunately, the signal is not in the `MyModel` class, which is a pity. – Kurt Bourbaki Feb 14 '22 at 13:38
an example of how to create a post_save signal (from http://djangosnippets.org/snippets/500/)
from django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
"""Create a matching profile whenever a user object is created."""
if created:
profile, new = UserProfile.objects.get_or_create(user=instance)
here is a thoughtful discussion on whether it's best to use signals or custom save methods https://web.archive.org/web/20120815022107/http://www.martin-geber.com/thought/2007/10/29/django-signals-vs-custom-save-method/
In my opinion using signals for this task is more robust, easier to read but lengthier.

- 489
- 6
- 14

- 5,042
- 4
- 28
- 24
-
This is the preferred way instead of messing with object internals, however, if you make modifications to the model in question, and not just creating another in the above example, **don't forget to call `instance.save()`**. So in this case, there is also a performance penalty since there will be one INSERT and one UPDATE query to the database. – Mike Shultz Jul 11 '15 at 17:39
-
The link to the signals vs. custom save methods is broken. – Sander Vanden Hautte Apr 24 '18 at 14:44
Overriding __init__()
will allow you to execute code when the model is instantiated. Don't forget to call the parent's __init__()
.

- 776,304
- 153
- 1,341
- 1,358
-
1Ah yes this was the answer. Don't know how I overlooked this. Thanks Ignacio. – ground5hark Feb 21 '10 at 23:57
You can override the create method with a custom manager or add a classmethod on the model class. https://docs.djangoproject.com/en/1.11/ref/models/instances/#creating-objects

- 5,414
- 4
- 26
- 33
The preferred answer is correct but the test to tell whether the object is being created doesn't work if your model derives from UUIDModel. The pk field will already have a value.
In this case, you can do this:
already_created = MyModel.objects.filter(pk=self.pk).exists()

- 43
- 5