mirror of https://github.com/django/django.git
Fixed #10672 -- Altered save_base to ensure that proxy models send a post_save signal.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10954 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
6cd37e0a1f
commit
81aedbd157
|
@ -411,29 +411,35 @@ class Model(object):
|
||||||
|
|
||||||
save.alters_data = True
|
save.alters_data = True
|
||||||
|
|
||||||
def save_base(self, raw=False, cls=None, force_insert=False,
|
def save_base(self, raw=False, cls=None, origin=None,
|
||||||
force_update=False):
|
force_insert=False, force_update=False):
|
||||||
"""
|
"""
|
||||||
Does the heavy-lifting involved in saving. Subclasses shouldn't need to
|
Does the heavy-lifting involved in saving. Subclasses shouldn't need to
|
||||||
override this method. It's separate from save() in order to hide the
|
override this method. It's separate from save() in order to hide the
|
||||||
need for overrides of save() to pass around internal-only parameters
|
need for overrides of save() to pass around internal-only parameters
|
||||||
('raw' and 'cls').
|
('raw', 'cls', and 'origin').
|
||||||
"""
|
"""
|
||||||
assert not (force_insert and force_update)
|
assert not (force_insert and force_update)
|
||||||
if not cls:
|
if cls is None:
|
||||||
cls = self.__class__
|
cls = self.__class__
|
||||||
meta = self._meta
|
meta = cls._meta
|
||||||
signal = True
|
if not meta.proxy:
|
||||||
signals.pre_save.send(sender=self.__class__, instance=self, raw=raw)
|
origin = cls
|
||||||
else:
|
else:
|
||||||
meta = cls._meta
|
meta = cls._meta
|
||||||
signal = False
|
|
||||||
|
if origin:
|
||||||
|
signals.pre_save.send(sender=origin, instance=self, raw=raw)
|
||||||
|
|
||||||
# If we are in a raw save, save the object exactly as presented.
|
# If we are in a raw save, save the object exactly as presented.
|
||||||
# That means that we don't try to be smart about saving attributes
|
# That means that we don't try to be smart about saving attributes
|
||||||
# that might have come from the parent class - we just save the
|
# that might have come from the parent class - we just save the
|
||||||
# attributes we have been given to the class we have been given.
|
# attributes we have been given to the class we have been given.
|
||||||
if not raw:
|
if not raw:
|
||||||
|
if meta.proxy:
|
||||||
|
org = cls
|
||||||
|
else:
|
||||||
|
org = None
|
||||||
for parent, field in meta.parents.items():
|
for parent, field in meta.parents.items():
|
||||||
# At this point, parent's primary key field may be unknown
|
# At this point, parent's primary key field may be unknown
|
||||||
# (for example, from administration form which doesn't fill
|
# (for example, from administration form which doesn't fill
|
||||||
|
@ -441,7 +447,8 @@ class Model(object):
|
||||||
if field and getattr(self, parent._meta.pk.attname) is None and getattr(self, field.attname) is not None:
|
if field and getattr(self, parent._meta.pk.attname) is None and getattr(self, field.attname) is not None:
|
||||||
setattr(self, parent._meta.pk.attname, getattr(self, field.attname))
|
setattr(self, parent._meta.pk.attname, getattr(self, field.attname))
|
||||||
|
|
||||||
self.save_base(cls=parent)
|
self.save_base(cls=parent, origin=org)
|
||||||
|
|
||||||
if field:
|
if field:
|
||||||
setattr(self, field.attname, self._get_pk_val(parent._meta))
|
setattr(self, field.attname, self._get_pk_val(parent._meta))
|
||||||
if meta.proxy:
|
if meta.proxy:
|
||||||
|
@ -492,8 +499,8 @@ class Model(object):
|
||||||
setattr(self, meta.pk.attname, result)
|
setattr(self, meta.pk.attname, result)
|
||||||
transaction.commit_unless_managed()
|
transaction.commit_unless_managed()
|
||||||
|
|
||||||
if signal:
|
if origin:
|
||||||
signals.post_save.send(sender=self.__class__, instance=self,
|
signals.post_save.send(sender=origin, instance=self,
|
||||||
created=(not record_exists), raw=raw)
|
created=(not record_exists), raw=raw)
|
||||||
|
|
||||||
save_base.alters_data = True
|
save_base.alters_data = True
|
||||||
|
|
|
@ -259,6 +259,33 @@ FieldError: Proxy model 'NoNewFields' contains model fields.
|
||||||
>>> OtherPerson._default_manager.all()
|
>>> OtherPerson._default_manager.all()
|
||||||
[<OtherPerson: barney>, <OtherPerson: wilma>]
|
[<OtherPerson: barney>, <OtherPerson: wilma>]
|
||||||
|
|
||||||
|
# Test save signals for proxy models
|
||||||
|
>>> from django.db.models import signals
|
||||||
|
>>> def make_handler(model, event):
|
||||||
|
... def _handler(*args, **kwargs):
|
||||||
|
... print u"%s %s save" % (model, event)
|
||||||
|
... return _handler
|
||||||
|
>>> h1 = make_handler('MyPerson', 'pre')
|
||||||
|
>>> h2 = make_handler('MyPerson', 'post')
|
||||||
|
>>> h3 = make_handler('Person', 'pre')
|
||||||
|
>>> h4 = make_handler('Person', 'post')
|
||||||
|
>>> signals.pre_save.connect(h1, sender=MyPerson)
|
||||||
|
>>> signals.post_save.connect(h2, sender=MyPerson)
|
||||||
|
>>> signals.pre_save.connect(h3, sender=Person)
|
||||||
|
>>> signals.post_save.connect(h4, sender=Person)
|
||||||
|
>>> dino = MyPerson.objects.create(name=u"dino")
|
||||||
|
MyPerson pre save
|
||||||
|
MyPerson post save
|
||||||
|
|
||||||
|
# Test save signals for proxy proxy models
|
||||||
|
>>> h5 = make_handler('MyPersonProxy', 'pre')
|
||||||
|
>>> h6 = make_handler('MyPersonProxy', 'post')
|
||||||
|
>>> signals.pre_save.connect(h5, sender=MyPersonProxy)
|
||||||
|
>>> signals.post_save.connect(h6, sender=MyPersonProxy)
|
||||||
|
>>> dino = MyPersonProxy.objects.create(name=u"pebbles")
|
||||||
|
MyPersonProxy pre save
|
||||||
|
MyPersonProxy post save
|
||||||
|
|
||||||
# A proxy has the same content type as the model it is proxying for (at the
|
# A proxy has the same content type as the model it is proxying for (at the
|
||||||
# storage level, it is meant to be essentially indistinguishable).
|
# storage level, it is meant to be essentially indistinguishable).
|
||||||
>>> ctype = ContentType.objects.get_for_model
|
>>> ctype = ContentType.objects.get_for_model
|
||||||
|
@ -266,7 +293,7 @@ FieldError: Proxy model 'NoNewFields' contains model fields.
|
||||||
True
|
True
|
||||||
|
|
||||||
>>> MyPersonProxy.objects.all()
|
>>> MyPersonProxy.objects.all()
|
||||||
[<MyPersonProxy: barney>, <MyPersonProxy: fred>]
|
[<MyPersonProxy: barney>, <MyPersonProxy: dino>, <MyPersonProxy: fred>, <MyPersonProxy: pebbles>]
|
||||||
|
|
||||||
>>> u = User.objects.create(name='Bruce')
|
>>> u = User.objects.create(name='Bruce')
|
||||||
>>> User.objects.all()
|
>>> User.objects.all()
|
||||||
|
|
Loading…
Reference in New Issue