Opened 18 years ago
Closed 17 years ago
#2936 closed defect (fixed)
[patch]override __hash__ method of django.db.base.Model
Reported by: | Owned by: | Adrian Holovaty | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | normal | Keywords: | |
Cc: | favo@…, canburak@… | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Since django Model has override __eq__
method, should override __hash__
method too (objects comparing equal should also hash to the
same value).
Attachments (1)
Change History (12)
by , 18 years ago
Attachment: | add_hash_to_model.diff added |
---|
comment:1 by , 18 years ago
Summary: | override __hash__ method of django.db.base.Model → [patch]override __hash__ method of django.db.base.Model |
---|
comment:3 by , 18 years ago
hmm... I just remember some strange situation that I meet. anyway it seems no need.
comment:4 by , 18 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
I was totally wrong to open this ticket, since http://docs.python.org/ref/customization.html:
If a class defines mutable objects and implements a __cmp__() or __eq__() method, it should not implement __hash__()
And django model is a mutable object. so we can't implement __hash__()
.
comment:5 by , 18 years ago
I think in this case the Python docs were mis-interpreted. The key
point to consider when writing a hash function is that two objects
that compare equal must hash equally, and the hash value cannot
change. Just because an object is mutable doesn't mean that these
rules will be violated. A mutable object may have a hash
that uses its mutable data as part of the hash implementation,
which would be unacceptable. But a mutable object can have a carefully
planned hash which only uses the immutable data in its calculation.
In particular, Django model instances will
usually simply use their id attribute as the hash, and so will be
perfectly acceptable as dictionary keys.
comment:6 by , 17 years ago
I agree with Ned here, I would expect len(set([Model.objects.get(pk=1), Model.objects.get(pk=1)])) to be 1, but it's 2. I'd be inclined to consider it as a bug.
comment:7 by , 17 years ago
Resolution: | invalid |
---|---|
Status: | closed → reopened |
I concur. Using sets to filter duplicates is a common, efficient idiom. We should be able to do the same with model instances, mutable or not. The very fact that model equality is determined by their id alone makes the question of mutability irrelevant.
Consider a contrived example:
x = set(Foo.objects.all()) for f in Foo.objects.all(): x.add(f)
As it now stands, you'll end up with two copies of each Foo model in the set, a clear violation of the "principle of least surprise", IMHO.
comment:8 by , 17 years ago
Please, could you send an email to django-developers? I think this has been rejected by the core developers, but your arguments are valid.
comment:9 by , 17 years ago
Triage Stage: | Unreviewed → Accepted |
---|
It hasn't been rejected. There's no need for an email, it's a reasonable request. The original ticket burned and died based on mistaken assumptions (as Ned correctly notes) and just never got onto the radar.
comment:10 by , 17 years ago
Cc: | added |
---|
comment:11 by , 17 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
add hash to django.db.model.base