#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.