[Solved]-Django pre_save signal does not work


You’re not setting the sender class for one.

from django.db.models.signals import pre_save
from myapp.models import MyModel
import logging

def my_callback(sender, **kwargs):
pre_save.connect(my_callback, sender=MyModel)

Secondly, if you’re using Django 1.3 you should use the new decorator syntax.

# Inside your models.py
from django.db import models
from django.db.models.signals import pre_save
from django.dispatch import receiver

class MyModel(models.Model):
    field1 = models.TextField()
    field2 = models.IntegerField()

@receiver(pre_save, sender=MyModel)
def mymodel_save_handler(sender, **kwargs):

That should do it, but I haven’t tested the code so let me know if it’s still broken.


The reason Eric’s answer made it work is because he got you to connect the signal inside models.py, so that when you then save the model via your website the signal handler is in the same process as the signal firer.

In examples 1 and 3 it’s easy to see why they didn’t work – you are saving in a different process (the website) to where your signal receivers are listening.

I wish I understood better why example 2 is also broken but I just debugged a similar issue in my own project while testing signals in the shell and it’s definitely something to do with signal senders and receivers not being able to ‘see’ each other.


logging.debug() is using the root logger, which handler level by default is 30 (‘WARNING’).

=> logging.debug('something') is just not doing anything at all (DEBUG level is 10 < 30). See http://docs.python.org/2/library/logging.html

The same test should be done with another custom logger, or by doing:

l = logging.getLogger()
def my_callback(sender, **kwargs):

The original question is not containing enough info to know if it’s the real problem the OP was facing (or part of it).
But surely the OP’s code was not going to work with my ./manage.py shell


as described in the django signals doc the pre_save signal accept 3 unique arguments (not keyword arguments) so, you need to edit your my_callback function to be as follow:

def my_callback(sender,instance, using, **kwargs):

Leave a comment