#9318: "Virtual" behaviour for signal dispatcher and model inheritance
-------------------------------------+-------------------------------------
     Reporter:  Alexander Artemenko  |                    Owner:  (none)
         Type:  Bug                  |                   Status:  new
    Component:  Core (Other)         |                  Version:  1.0
     Severity:  Normal               |               Resolution:
     Keywords:  model inheritance,   |             Triage Stage:  Accepted
  signals, dispatch, proxy,          |
  subclass                           |
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  1
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Aymeric Augustin):

 * type:  New feature => Bug


Comment:

 I hit this bug today.

 It's really a silent data loss issue: creating a proxy model shouldn't
 disable behavior of the original model.

 I'm applying the following patch to Django until this is resolved:

 {{{
 --- a/django/db/models/base.py  2016-12-07 17:09:16.000000000 +0100
 +++ b/django/db/models/base.py  2016-12-07 17:13:18.000000000 +0100
 @@ -810,13 +810,12 @@
          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 len(update_fields) > 0
 -        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:
 -            signals.pre_save.send(sender=origin, instance=self, raw=raw,
 using=using,
 +            signals.pre_save.send(sender=cls, instance=self, raw=raw,
 using=using,
                                    update_fields=update_fields)
          with transaction.atomic(using=using, savepoint=False):
              if not raw:
 @@ -829,7 +828,7 @@

          # Signal that the save is complete
          if not meta.auto_created:
 -            signals.post_save.send(sender=origin, instance=self,
 created=(not updated),
 +            signals.post_save.send(sender=cls, instance=self,
 created=(not updated),
                                     update_fields=update_fields, raw=raw,
 using=using)

      save_base.alters_data = True
 }}}

 IMO this is the correct way to fix the issue. I understand the concern
 about backwards compatibility but I have a hard time figuring out a
 realistic scenario where developers would purposefully rely on this bug.

--
Ticket URL: <https://code.djangoproject.com/ticket/9318#comment:31>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/070.630e023c9042a3fea04a8cbdf44a8229%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to