Opened 3 weeks ago
Closed 3 weeks ago
#37309 closed Bug (fixed)
`Model.__eq__` treats distinct unsaved composite-PK instances as equal
| Reported by: | Denny Biasiolli | Owned by: | Denny Biasiolli |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 5.2 |
| Severity: | Normal | Keywords: | compositeprimarykey _is_pk_set |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | yes | UI/UX: | no |
Description (last modified by )
Model.__eq__ still uses pk is None to decide whether an instance is unsaved. That is wrong for composite primary keys (pk is a tuple) and for db_default PKs (DatabaseDefault is not None).
>>> User() == User() True >>> User(tenant_id=1) == User(tenant_id=1) True
Documented contract (and simple-PK behavior since #18864 / #18250) is that unsaved instances are equal only to themselves. __hash__ already uses _is_pk_set() and raises for an unset PK.
The XML serializer has the same leftover (if obj.pk is not None) and emits pk='["None", "None"]' for an unsaved composite instance instead of omitting the attribute.
Proposed fix: use _is_pk_set() in both places, matching __hash__ and the rest of the #373 conversion.
Change History (8)
comment:1 by , 3 weeks ago
| Description: | modified (diff) |
|---|
comment:2 by , 3 weeks ago
| Description: | modified (diff) |
|---|
comment:3 by , 3 weeks ago
| Triage Stage: | Unreviewed → Ready for checkin |
|---|
comment:6 by , 3 weeks ago
| Resolution: | fixed |
|---|---|
| Status: | closed → new |
comment:7 by , 3 weeks ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:8 by , 3 weeks ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |
Small suggestion to move the release note and split into two commits, otherwise looks g2g.