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
post_delete
signal. That is when I remove post_delete
signal from this handler,instance.supertask is not None
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
?
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.