Overriding the Model.create() method?

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?


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)

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 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.


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.)

    链接地址: http://www.djcxy.com/p/25378.html

    上一篇: 如何在Django中实现EAV

    下一篇: 重写Model.create()方法?