Reputation: 636
I have a problem with django model objects where I have overridden __hash__
() for some slightly complex uniqueness/distinctiveness constraints that I want to enforce when I use them. This is working fine with objects that I have just directly instantiated in memory, but not with ones I retrieve from the database.
Like this:
class Animal(models.Model):
name = model.Charfield('name', max_length=10)
def__hash__(self):
return len(self.name) # silly example for purposes of illustration
and then this:
>> a = models.Animal(name='cat')
>> b = models.Animal(name='dog')
>> len(set((a,b))
> 1
>> a.save()
>> b.save()
>> len(set(models.Animal.objects.all()))
> 2
Hmm. Whatever hash function is being used here, it ain't mine. I guess it's something related to lazy fetching / objects not yet in a fully instantiated state, but how to get round it?
Upvotes: 0
Views: 366
Reputation: 154504
This is because you have implemented __hash__
without implementing __eq__
. Implement __eq__
as well and you should be good to go.
The length of set([a, b])
is 1
because Django defines a default __eq__
function which compares the primary keys of the objects — so before they are saved, both with have an id
of None
, so a == b
will be True
. After they are saved, they will both have been assigned different primary keys, so a != b
will be True
.
Upvotes: 3