#16458: Equality operator on django.db.models.Model not commutative
-------------------------------------+-------------------------------------
     Reporter:  freek.wiekmeijer@…   |                    Owner:  anonymous
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  1.3
  (models, ORM)                      |               Resolution:
     Severity:  Normal               |             Triage Stage:  Accepted
     Keywords:                       |      Needs documentation:  1
    Has patch:  1                    |  Patch needs improvement:  1
  Needs tests:  0                    |                    UI/UX:  0
Easy pickings:  0                    |
-------------------------------------+-------------------------------------

Comment (by akaariai):

 I really do think the correct fix is making proxy models equal to their
 concrete parent if PKs match, but not extending the equality to multitable
 inheritance. Multitable inheritance equality could be backwards
 incompatible (see the admin `NestedCollector` fix for an example), the
 equality is hard to implement for models which have multiple primary keys
 (see comment:15, and an example in the end of this comment), and it will
 make eq somewhat slower.

 In my opinion the best way forward is a new attribute, `concrete_model`
 which is always the first concrete parent for proxy models, or self for
 concrete models. This attribute would have use in other parts of the code,
 too, simplifying some cases using proxy_for_model currently. In addition
 proxy_for_model should be fixed in a way where it actually points to the
 parent model. Now it points to the first concrete parent. Many parts of
 Django assumes that it points to the parent model (proxy or not) and thus
 can produce a "proxy chain".

 I am willing to write another patch which implements this.

 Last, a stupid little example of what kind of problems multitable multi-
 inheritance can cause for `__eq__`:
 {{{
 class A:
     id_a = IntegerField(primary_key=True)

 class B:
     id_b = IntegerField(primary_key=True)

 class C(A, B):
     pass

 class D(A, B):
     pass
 }}}
 Now, you can have c = C(id_a=1, id_b=1) and d = D(id_a=1, id_b=2). Are c
 and d equal or not? They both have same id_a which is a primary key, so
 they are. They have different id_b fields, so they aren't. So, you can't
 have bullet-proof `__eq__` for multitable multi-inheritance cases. (Yes, I
 admit this example is a stretch).

-- 
Ticket URL: <https://code.djangoproject.com/ticket/16458#comment:17>
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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to