Django:在post_signal处理程序中引发DoesNotExist错误

axr492tv  于 2023-07-01  发布在  Go
关注(0)|答案(1)|浏览(107)

尝试删除Task示例及其子任务时,我遇到了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'

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.

到目前为止,我已经弄清楚了错误与信号处理程序有关,因为当
1.处理程序不处理post_delete信号。也就是说,当我从这个处理程序中删除post_delete信号时,

  1. instance.supertask is not None
    1.不存在instance.subtasks
    这些情况是相互排斥的。如果处理程序不处理post_delete,那么是否处理instance.supertask is None并不重要。如果instance.supertask is not None,则示例是否有子任务无关紧要。如果示例有子任务,则instance.supertask is None与否无关紧要。
    对于上述情况,不会引发错误,并且delete()方法成功完成了其工作。该错误仅在处理程序处理post_delete信号时引发,并且如果它有子任务,则没有与示例相关的超级任务。
    在进入if语句时引发错误。
    下面是处理程序:
@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.

但我仍然要执行这段代码每当我删除任务。为什么会出现这个错误,如何调试它?
更新:
如果我在处理程序中打印dir(instance),它就有'supertask'。为什么我不能使用instance.supertask

j7dteeu8

j7dteeu81#

来自文件
请注意,该对象将不再位于数据库中,因此要非常小心地处理此示例。
所以我必须使用pre_delete代替。

相关问题