英文:
Django : DoesNotExist Error raised in post_signal handler
问题
I will provide translations for the non-code portions of the text you've provided:
"Trying to delete a Task
instance with its subtasks, I encounter DoesNotExist: Task matching query does not exist
."
错误消息如下:
"Traceback (most recent call last):
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 218, in get
rel_obj = self.field.get_cached_value(instance)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/mixins.py", line 15, in get_cached_value
return instance._state.fields_cache[cache_name]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'supertask'"
以下是错误消息:
"Traceback (most recent call last):
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 218, in get
rel_obj = self.field.get_cached_value(instance)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/mixins.py", line 15, in get_cached_value
return instance._state.fields_cache[cache_name]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'supertask'"
During handling of the above exception, another exception occurred:
在处理上述异常时,发生了另一个异常:
"Traceback (most recent call last):
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/crackers/views.py", line 73, in delete
print(task.delete())
^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/base.py", line 1132, in delete
return collector.delete()
^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/deletion.py", line 512, in delete
signals.post_delete.send(
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/dispatch/dispatcher.py", line 176, in send
return [
^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/dispatch/dispatcher.py", line 177, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/crackers/signals.py", line 10, in reassess_achievement
if instance.supertask is not None and instance.supertask.completed == False:
^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 236, in get
rel_obj = self.get_object(instance)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 199, in get_object
return qs.get(self.field.get_reverse_related_filter(instance))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/query.py", line 637, in get
raise self.model.DoesNotExist(
crackers.models.Task.DoesNotExist: Task matching query does not exist."
到目前为止,我已经发现错误与信号处理程序有关,因为在以下情况下不会出现相同的错误:
- 该处理程序不处理
post_delete
信号。也就是说,当我从此处理程序中删除post_delete
信号时, instance.supertask
不是 None,- 不存在
instance.subtasks
。
这些情况是互斥的。如果处理程序不处理 post_delete
,那么 instance.supertask
是否为 None 都无关紧要。如果 instance.supertask
不为 None,则实例是否具有子任务都无关紧要。如果实例具有子任务,则 instance.supertask
是否为 None 都无关紧要。
对于上述情况,不会引发错误,并且 delete()
方法成功完成其工作。只有当处理程序处理 post_delete
信号且与实例没有关联的 supertask 时才会引发错误。
错误是因为进入 if 语句时引发的。
以下是处理程序的代码:
@receiver([post_save, post_delete], sender=Task)
def reassess_achievement(sender, instance, **kwargs):
print('*'*100) # 执行
if instance.supertask is not None and instance.supertask.completed == False:
print('#'*100) # 未执行
...
# 对于其他情况,没有任务要执行。
但是,我仍然必须在删除任务时执行此代码。为什么会引发此错误,以及如何调试它?
更新:
如果我在处理程序中打印 dir(instance)
,它确实具有 'supertask'
。为什么我不能使用 instance.supertask
?
英文:
Trying to delete a Task
instance with its subtasks, I encounter DoesNotExist: Task matching query does not exist
.
The following is the error message:
Traceback (most recent call last):
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 218, in __get__
rel_obj = self.field.get_cached_value(instance)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/mixins.py", line 15, in get_cached_value
return instance._state.fields_cache[cache_name]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'supertask'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/crackers/views.py", line 73, in delete
print(task.delete())
^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/base.py", line 1132, in delete
return collector.delete()
^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/deletion.py", line 512, in delete
signals.post_delete.send(
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/dispatch/dispatcher.py", line 176, in send
return [
^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/dispatch/dispatcher.py", line 177, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/crackers/signals.py", line 10, in reassess_achievement
if instance.supertask is not None and instance.supertask.completed == False:
^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 236, in __get__
rel_obj = self.get_object(instance)
^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 199, in get_object
return qs.get(self.field.get_reverse_related_filter(instance))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/thebjko/dev/TrackCracker/venv/lib/python3.11/site-packages/django/db/models/query.py", line 637, in get
raise self.model.DoesNotExist(
crackers.models.Task.DoesNotExist: Task matching query does not exist.
So far, I have figured out that the error is related to signal handler, since the same error does not occur when
- the handler does not handle
post_delete
signal. That is when I removepost_delete
signal from this handler, instance.supertask is not None
- there does not exist
instance.subtasks
.
These cases are mutually exclusive. If the handler does not handle post_delete
, it does not matter if instance.supertask is None
or not. If instance.supertask is not None
, it does not matter if the instance has subtasks or not. If the instance has subtasks, it does not matter if instance.supertask is None
or not.
For the above cases, the error is not raised and delete()
method does its job successfully. The error is only raised when the handler handles post_delete
signal, and there is no supertask related with the instance if it has subtasks.
The error is raised as it enters if statement.
The following is the handler:
@receiver([post_save, post_delete], sender=Task)
def reassess_achievement(sender, instance, **kwargs):
print('*'*100) # executed
if instance.supertask is not None and instance.supertask.completed == False:
print('#'*100) # not executed
...
# No job for other cases.
But I still have to execute this code whenever I delete task. Why is this error raised and how can I debug it?
UPDATE:
If I print dir(instance)
inside the handler, it does have 'supertask'
. Why can't I use instance.supertask
?
答案1
得分: 0
从文档中:
> 请注意,对象将不再存在于数据库中,因此对这个实例要非常小心。
所以我必须使用pre_delete
代替。
英文:
From documentation
> Note that the object will no longer be in the database, so be very careful what you do with this instance.
So I have to use pre_delete
instead.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论