【问题标题】:Django 1.7: Passing around unsaved instances throws "unhashable" exceptionDjango 1.7:传递未保存的实例会引发“unhashable”异常
【发布时间】:2014-09-28 02:51:36
【问题描述】:

我目前正在迁移到 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

【问题讨论】:

  • 我不知道信号参数是可散列的任何要求。您能否显示产生错误的实际代码以及完整的回溯?
  • 刚刚添加了一个例子
  • 请提供完整的回溯。
  • 还添加了完整的回溯

标签: python django django-models django-1.7


【解决方案1】:

看起来 Django 将sender 存储在缓存中,用于在信号分发期间进行查找。这要求sender 是可散列的,这在没有pk 的模型实例上不起作用。

这不会影响pre_save 等人的原因。也就是说,按照惯例,sender 是模型 class,而不是模型 instanceinstance 在它自己的参数中传递。见the documentation

解决方案很简单——使用类作为sender,并将实例作为参数传递。

(如果这在它只是偶然之前起作用。修复的bug 导致所有未保存的模型实例评估为相等。)

【讨论】:

  • 是的,在再次查看回溯后,我得出了相同的结论。感谢发帖
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-18
  • 1970-01-01
相关资源
最近更新 更多