Django 1.7: Walking around unsaved instances throws an "uncorrectable" exception
I am currently migrating to Django 1.7. I have some signals that send an unsaved model instance which is now being cast
TypeError: Model instances without primary key value are unhashable
I'm wondering how Django passes a
signal around an instance? I go through the docs and even found a commit that implemented this in 1.7 ( https://github.com/django/django/commit/6af05e7a0f0e4604d6a67899acaa99d73ec0dfaa ) and I just don't know how to do it even works.
Can someone explain to me how pre_save will get around this or how I can get around this limitation myself? Thank.
Sample code below:
from django.dispatch import Signal send_text = Signal() unsaved_model = SomeModel() # note that neither `create` or `.save()` are being called send_text.send(sender=unsaved_model) # error gets thrown when this gets called
File "/home/ubuntu/fangsterr-app/notifications/models.py", line 43, in send send_text.send(sender=self) File "/home/ubuntu/virtualenvs/venv-2.7.5/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 194, in send if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS: File "/home/ubuntu/virtualenvs/venv-2.7.5/lib/python2.7/site-packages/django/db/models/base.py", line 484, in __hash__ raise TypeError("Model instances without primary key value are unhashable") TypeError: Model instances without primary key value are unhashable
source to share
It looks like Django stores
in a cache that it uses to look up while sending a signal. This requires it to
be hashable, which doesn't work on a model instance without
The reason for this does not affect
et al. is that, by convention,
is a model class, not a model instance.
passed in its own argument. See the documentation .
The solution is easy to use the class as
and pass an instance as an argument.
(If it worked before it was just an accident. Fixed a bug where all uncolored instances of the model were evaluated as equal.)
source to share