我目前正在迁移到Django 1.7。我有一些信号传递未保存的模型实例,现在抛出TypeError: Model instances without primary key value are unhashable
。
我想知道Django pre_save
信号如何在实例周围传递?我正在查看文档,甚至找到了在1.7(https://github.com/django/django/commit/6af05e7a0f0e4604d6a67899acaa99d73ec0dfaa)中实现此功能的提交,我只是不知道它是如何工作的。
有人可以向我解释pre_save是如何解决这个问题的,或者我如何绕过这个限制?感谢。
以下示例代码:
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
答案 0 :(得分:7)
看起来Django将sender
存储在一个缓存中,用于在信号调度期间进行查找。这需要sender
可以清除,这对于没有pk
的模型实例不起作用。
这不会影响pre_save
等人的原因。按照惯例,sender
是模型类,而不是模型实例。 instance
在其自己的参数中传递。请参阅the documentation。
该解决方案很容易使用该类作为sender
,并将该实例作为参数传递。
(如果这只是在偶然发生之前有效。修复的bug导致所有未保存的模型实例评估为相等。)