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 pre_save

signal around an instance? I go through the docs and even found a commit that implemented this in 1.7 ( ) 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/", line 43, in send
  File "/home/ubuntu/virtualenvs/venv-2.7.5/lib/python2.7/site-packages/django/dispatch/", 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/", 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

1 answer

It looks like Django stores sender

in a cache that it uses to look up while sending a signal. This requires it to sender

be hashable, which doesn't work on a model instance without pk


The reason for this does not affect pre_save

et al. is that, by convention, sender

is a model class, not a model instance. instance

passed in its own argument. See the documentation .

The solution is easy to use the class as sender

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.)



All Articles