#18250 closed Bug (fixed)
Comparing two unsaved model objects
Reported by: | Owned by: | Yarden | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | compare model |
Cc: | moritz.sichert@… | Triage Stage: | Accepted |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
if i do this:
User(email="exmple@…") == User(email="exmple22@…")
it will return True!
but if i save them- it will return False.
this is because the eq magic method tries to compare their PK's. if no pk it will return None. so None == None...
django.db.models.base line 383
def eq
Change History (10)
comment:1 by , 13 years ago
Type: | Uncategorized → Bug |
---|
comment:2 by , 13 years ago
Cc: | added |
---|---|
Triage Stage: | Unreviewed → Design decision needed |
Version: | 1.3 → master |
comment:3 by , 13 years ago
It doesn't have to, you can have it fall back to an identity comparison if the pks are None.
comment:4 by , 13 years ago
Triage Stage: | Design decision needed → Accepted |
---|
comment:5 by , 13 years ago
Cc: | removed |
---|
comment:6 by , 13 years ago
Cc: | added |
---|
comment:7 by , 13 years ago
How about something like:
def __eq__(self, other): if not isinstance(other, Model): return False if self._get_pk_val() is None: return id(self) == id(other) # Symmetric if self._meta.concrete_class != other._meta.concrete_class: return False return self._get_pk_val() == other._get_pk_val()
Not tested...
Version 0, edited 13 years ago by (next)
comment:9 by , 11 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
I think this one is duplicate of #18864 (it has a slightly bigger scope as it also deals with __hash__
).
comment:10 by , 11 years ago
Resolution: | duplicate → fixed |
---|
Note:
See TracTickets
for help on using tickets.
Changing the __eq__ method to check if the pk value is None would cause that all non-saved model objects would return False when being compared: