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 ( 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

      

Traceback:

  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

      

+3


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

+6


source







All Articles