#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 django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
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