Django - Overriding the Model.create() method?

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)

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:

  1. use signals (read more here in the official docs)
  2. 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.)


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.