0
0
mirror of https://github.com/django/django.git synced 2024-11-24 02:47:35 +01:00

Fixed 9318 -- Forwarded signals from proxy models to their concrete models.

This commit is contained in:
Daniel Nunes 2024-03-22 11:55:22 +00:00
parent 8dbfef4695
commit ce86a0b39f
4 changed files with 16 additions and 11 deletions

View File

@ -459,14 +459,16 @@ class ModelState:
class Model(AltersData, metaclass=ModelBase):
def __init__(self, *args, **kwargs):
# Alias some things as locals to avoid repeat global lookups
cls = self.__class__
cls = sender = self.__class__
opts = self._meta
_setattr = setattr
_DEFERRED = DEFERRED
if opts.abstract:
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
self._state = ModelState()
@ -569,7 +571,7 @@ class Model(AltersData, metaclass=ModelBase):
f"{unexpected_names}"
)
super().__init__()
post_init.send(sender=cls, instance=self)
post_init.send(sender=sender, instance=self)
@classmethod
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)
assert not (force_insert and (force_update or update_fields))
assert update_fields is None or update_fields
cls = origin = self.__class__
# Skip proxies, but keep the origin as the proxy model.
cls = self.__class__
if cls._meta.proxy:
cls = cls._meta.concrete_model
meta = cls._meta
if not meta.auto_created:
pre_save.send(
sender=origin,
sender=cls,
instance=self,
raw=raw,
using=using,
@ -992,7 +993,7 @@ class Model(AltersData, metaclass=ModelBase):
# Signal that the save is complete
if not meta.auto_created:
post_save.send(
sender=origin,
sender=cls,
instance=self,
created=(not updated),
update_fields=update_fields,

View File

@ -456,6 +456,8 @@ class Collector:
# send pre_delete signals
for model, obj in self.instances_with_model():
if not model._meta.auto_created:
if model._meta.proxy:
model = model._meta.concrete_model
signals.pre_delete.send(
sender=model,
instance=obj,
@ -504,6 +506,8 @@ class Collector:
deleted_counter[model._meta.label] += count
if not model._meta.auto_created:
if model._meta.proxy:
model = model._meta.concrete_model
for obj in instances:
signals.post_delete.send(
sender=model,

View File

@ -343,5 +343,5 @@ class DeferDeletionSignalsTests(TestCase):
def test_delete_defered_proxy_model(self):
Proxy.objects.only("value").get(pk=self.item_pk).delete()
self.assertEqual(self.pre_delete_senders, [Proxy])
self.assertEqual(self.post_delete_senders, [Proxy])
self.assertEqual(self.pre_delete_senders, [Item])
self.assertEqual(self.post_delete_senders, [Item])

View File

@ -243,7 +243,7 @@ class ProxyModelTests(TestCase):
signals.post_save.connect(h4, sender=Person)
MyPerson.objects.create(name="dino")
self.assertEqual(output, ["MyPerson pre save", "MyPerson post save"])
self.assertEqual(output, ["Person pre save", "Person post save"])
output = []
@ -255,7 +255,7 @@ class ProxyModelTests(TestCase):
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.post_save.disconnect(h2, sender=MyPerson)