17

Personally I like using signals:

from django.db import models
from django.db.models.signals import pre_save

class MyModel(models.Model):

    ...

def custom_action_before_saving(sender, instance, *args, **kwargs):
    ...

pre_save.connect(custom_action_before_saving, sender=MyModel)

But I wonder if there're some times or task when is better override the save method in a model class:

from django.db import models

class MyModel(models.Model):
    ...

    def save(self):
        ...
        super(MyModel, self).save()

I am asking this because there's an example of overriding the save() method (link provided above) in Django's Documentation page, so I don't think it's a bad practice.

Let's take pre_save() as example, docs says:

This is sent at the beginning of a model’s save() method.

Does it means that overriding save has the same effect over performance that using signals?

Gocht
  • 9,924
  • 3
  • 42
  • 81
  • 5
    Possible duplicate of [Django: When to customize save vs using post-save signal](http://stackoverflow.com/questions/5597378/django-when-to-customize-save-vs-using-post-save-signal) – Shang Wang Mar 11 '16 at 20:59
  • signals can be messier, needing to take into account duplicate signals, https://docs.djangoproject.com/en/1.9/topics/signals/#preventing-duplicate-signals, loading of fixtures (if you are into that) triggering signals when you might not want to and other vagaries... – lukeaus Mar 11 '16 at 21:00
  • @luke_aus isn't the same that using `if self....:` overriding save to avoid code executions in some cases? – Gocht Mar 11 '16 at 21:16
  • @Gocht save() methods aren't triggered by loading of fixtures. – lukeaus Mar 12 '16 at 17:17
  • @luke_aus thatś a good point, bulk methods trigger signals? – Gocht Mar 12 '16 at 18:35
  • @Gocht fixtures do, not sure about bulk_create() – lukeaus Mar 13 '16 at 22:34
  • @luke_aus From [docs](https://docs.djangoproject.com/es/1.9/ref/models/querysets/#bulk-create): _The model’s save() method will not be called, and the pre_save and post_save signals will not be sent._ – Gocht Mar 14 '16 at 22:30

2 Answers2

28

You wouldn't find any performance difference. Neither of them are hacks or "wrong" coding method. It's all how you like it.

You can use signals if you are getting circular imports when overriding save method or when saving from somewhere else.

I follow a pattern where, if the changes belong to same model, override the save method, else if they belong to a different model which isn't linked to the current model (by one to one or one to many), use signals.

anonDuck
  • 1,337
  • 1
  • 9
  • 15
4

Choosing between overriding the save method or utilizing signals isn't really a question of performance or best-practice. As the documentation says signals are mainly a great way to keep apps decoupled while stile being able to communicate with each other.

Compared to overriding the save method signals also feels more natural to combine with Celery to off-load certain processing to the background.

Andreas Bergström
  • 13,891
  • 5
  • 59
  • 53