diff --git a/AUTHORS b/AUTHORS index 948b73ce4c..18035835b2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -296,6 +296,7 @@ answer newbie questions, and generally made Django that much better: Amit Upadhyay Geert Vanderkelen viestards.lists@gmail.com + George Vilches Vlado Milton Waddams wam-djangobug@wamber.net diff --git a/django/db/models/base.py b/django/db/models/base.py index f7b9069cce..fa1e0224d0 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -247,6 +247,7 @@ class Model(object): qn(self._meta.order_with_respect_to.column)) cursor.execute(subsel, (getattr(self, self._meta.order_with_respect_to.attname),)) db_values.append(cursor.fetchone()[0]) + record_exists = False if db_values: cursor.execute("INSERT INTO %s (%s) VALUES (%s)" % \ (qn(self._meta.db_table), ','.join(field_names), @@ -261,7 +262,8 @@ class Model(object): transaction.commit_unless_managed() # Run any post-save hooks. - dispatcher.send(signal=signals.post_save, sender=self.__class__, instance=self) + dispatcher.send(signal=signals.post_save, sender=self.__class__, + instance=self, created=(not record_exists)) save.alters_data = True diff --git a/tests/modeltests/signals/__init__.py b/tests/modeltests/signals/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/modeltests/signals/models.py b/tests/modeltests/signals/models.py new file mode 100644 index 0000000000..d41142135e --- /dev/null +++ b/tests/modeltests/signals/models.py @@ -0,0 +1,85 @@ +""" +Testing signals before/after saving and deleting. +""" + +from django.db import models +from django.dispatch import dispatcher + +class Person(models.Model): + first_name = models.CharField(max_length=20) + last_name = models.CharField(max_length=20) + + def __unicode__(self): + return u"%s %s" % (self.first_name, self.last_name) + + +def pre_save_test(sender, instance, **kwargs): + print 'pre_save signal,', instance + +def post_save_test(sender, instance, **kwargs): + print 'post_save signal,', instance + if 'created' in kwargs: + if kwargs['created']: + print 'Is created' + else: + print 'Is updated' + +def pre_delete_test(sender, instance, **kwargs): + print 'pre_delete signal,', instance + print 'instance.id is not None: %s' % (instance.id != None) + +def post_delete_test(sender, instance, **kwargs): + print 'post_delete signal,', instance + print 'instance.id is None: %s' % (instance.id == None) + +__test__ = {'API_TESTS':""" +>>> dispatcher.connect(pre_save_test, signal=models.signals.pre_save) +>>> dispatcher.connect(post_save_test, signal=models.signals.post_save) +>>> dispatcher.connect(pre_delete_test, signal=models.signals.pre_delete) +>>> dispatcher.connect(post_delete_test, signal=models.signals.post_delete) + +>>> p1 = Person(first_name='John', last_name='Smith') +>>> p1.save() +pre_save signal, John Smith +post_save signal, John Smith +Is created + +>>> p1.first_name = 'Tom' +>>> p1.save() +pre_save signal, Tom Smith +post_save signal, Tom Smith +Is updated + +>>> p1.delete() +pre_delete signal, Tom Smith +instance.id is not None: True +post_delete signal, Tom Smith +instance.id is None: True + +>>> p2 = Person(first_name='James', last_name='Jones') +>>> p2.id = 99999 +>>> p2.save() +pre_save signal, James Jones +post_save signal, James Jones +Is created + +>>> p2.id = 99998 +>>> p2.save() +pre_save signal, James Jones +post_save signal, James Jones +Is created + +>>> p2.delete() +pre_delete signal, James Jones +instance.id is not None: True +post_delete signal, James Jones +instance.id is None: True + +>>> Person.objects.all() +[] + +>>> dispatcher.disconnect(post_delete_test, signal=models.signals.post_delete) +>>> dispatcher.disconnect(pre_delete_test, signal=models.signals.pre_delete) +>>> dispatcher.disconnect(post_save_test, signal=models.signals.post_save) +>>> dispatcher.disconnect(pre_save_test, signal=models.signals.pre_save) +"""}