mirror of
https://github.com/django/django.git
synced 2025-07-07 11:19:12 +00:00
Fixed 9318 -- Forwarded signals from proxy models to their concrete models.
This commit is contained in:
parent
8dbfef4695
commit
ce86a0b39f
@ -459,14 +459,16 @@ class ModelState:
|
|||||||
class Model(AltersData, metaclass=ModelBase):
|
class Model(AltersData, metaclass=ModelBase):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
# Alias some things as locals to avoid repeat global lookups
|
# Alias some things as locals to avoid repeat global lookups
|
||||||
cls = self.__class__
|
cls = sender = self.__class__
|
||||||
opts = self._meta
|
opts = self._meta
|
||||||
_setattr = setattr
|
_setattr = setattr
|
||||||
_DEFERRED = DEFERRED
|
_DEFERRED = DEFERRED
|
||||||
if opts.abstract:
|
if opts.abstract:
|
||||||
raise TypeError("Abstract models cannot be instantiated.")
|
raise TypeError("Abstract models cannot be instantiated.")
|
||||||
|
|
||||||
pre_init.send(sender=cls, args=args, kwargs=kwargs)
|
if sender._meta.proxy:
|
||||||
|
sender = sender._meta.concrete_model
|
||||||
|
pre_init.send(sender=sender, args=args, kwargs=kwargs)
|
||||||
|
|
||||||
# Set up the storage for instance state
|
# Set up the storage for instance state
|
||||||
self._state = ModelState()
|
self._state = ModelState()
|
||||||
@ -569,7 +571,7 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
f"{unexpected_names}"
|
f"{unexpected_names}"
|
||||||
)
|
)
|
||||||
super().__init__()
|
super().__init__()
|
||||||
post_init.send(sender=cls, instance=self)
|
post_init.send(sender=sender, instance=self)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_db(cls, db, field_names, values):
|
def from_db(cls, db, field_names, values):
|
||||||
@ -950,14 +952,13 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
using = using or router.db_for_write(self.__class__, instance=self)
|
using = using or router.db_for_write(self.__class__, instance=self)
|
||||||
assert not (force_insert and (force_update or update_fields))
|
assert not (force_insert and (force_update or update_fields))
|
||||||
assert update_fields is None or update_fields
|
assert update_fields is None or update_fields
|
||||||
cls = origin = self.__class__
|
cls = self.__class__
|
||||||
# Skip proxies, but keep the origin as the proxy model.
|
|
||||||
if cls._meta.proxy:
|
if cls._meta.proxy:
|
||||||
cls = cls._meta.concrete_model
|
cls = cls._meta.concrete_model
|
||||||
meta = cls._meta
|
meta = cls._meta
|
||||||
if not meta.auto_created:
|
if not meta.auto_created:
|
||||||
pre_save.send(
|
pre_save.send(
|
||||||
sender=origin,
|
sender=cls,
|
||||||
instance=self,
|
instance=self,
|
||||||
raw=raw,
|
raw=raw,
|
||||||
using=using,
|
using=using,
|
||||||
@ -992,7 +993,7 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
# Signal that the save is complete
|
# Signal that the save is complete
|
||||||
if not meta.auto_created:
|
if not meta.auto_created:
|
||||||
post_save.send(
|
post_save.send(
|
||||||
sender=origin,
|
sender=cls,
|
||||||
instance=self,
|
instance=self,
|
||||||
created=(not updated),
|
created=(not updated),
|
||||||
update_fields=update_fields,
|
update_fields=update_fields,
|
||||||
|
@ -456,6 +456,8 @@ class Collector:
|
|||||||
# send pre_delete signals
|
# send pre_delete signals
|
||||||
for model, obj in self.instances_with_model():
|
for model, obj in self.instances_with_model():
|
||||||
if not model._meta.auto_created:
|
if not model._meta.auto_created:
|
||||||
|
if model._meta.proxy:
|
||||||
|
model = model._meta.concrete_model
|
||||||
signals.pre_delete.send(
|
signals.pre_delete.send(
|
||||||
sender=model,
|
sender=model,
|
||||||
instance=obj,
|
instance=obj,
|
||||||
@ -504,6 +506,8 @@ class Collector:
|
|||||||
deleted_counter[model._meta.label] += count
|
deleted_counter[model._meta.label] += count
|
||||||
|
|
||||||
if not model._meta.auto_created:
|
if not model._meta.auto_created:
|
||||||
|
if model._meta.proxy:
|
||||||
|
model = model._meta.concrete_model
|
||||||
for obj in instances:
|
for obj in instances:
|
||||||
signals.post_delete.send(
|
signals.post_delete.send(
|
||||||
sender=model,
|
sender=model,
|
||||||
|
@ -343,5 +343,5 @@ class DeferDeletionSignalsTests(TestCase):
|
|||||||
|
|
||||||
def test_delete_defered_proxy_model(self):
|
def test_delete_defered_proxy_model(self):
|
||||||
Proxy.objects.only("value").get(pk=self.item_pk).delete()
|
Proxy.objects.only("value").get(pk=self.item_pk).delete()
|
||||||
self.assertEqual(self.pre_delete_senders, [Proxy])
|
self.assertEqual(self.pre_delete_senders, [Item])
|
||||||
self.assertEqual(self.post_delete_senders, [Proxy])
|
self.assertEqual(self.post_delete_senders, [Item])
|
||||||
|
@ -243,7 +243,7 @@ class ProxyModelTests(TestCase):
|
|||||||
signals.post_save.connect(h4, sender=Person)
|
signals.post_save.connect(h4, sender=Person)
|
||||||
|
|
||||||
MyPerson.objects.create(name="dino")
|
MyPerson.objects.create(name="dino")
|
||||||
self.assertEqual(output, ["MyPerson pre save", "MyPerson post save"])
|
self.assertEqual(output, ["Person pre save", "Person post save"])
|
||||||
|
|
||||||
output = []
|
output = []
|
||||||
|
|
||||||
@ -255,7 +255,7 @@ class ProxyModelTests(TestCase):
|
|||||||
|
|
||||||
MyPersonProxy.objects.create(name="pebbles")
|
MyPersonProxy.objects.create(name="pebbles")
|
||||||
|
|
||||||
self.assertEqual(output, ["MyPersonProxy pre save", "MyPersonProxy post save"])
|
self.assertEqual(output, ["Person pre save", "Person post save"])
|
||||||
|
|
||||||
signals.pre_save.disconnect(h1, sender=MyPerson)
|
signals.pre_save.disconnect(h1, sender=MyPerson)
|
||||||
signals.post_save.disconnect(h2, sender=MyPerson)
|
signals.post_save.disconnect(h2, sender=MyPerson)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user