django-model-utils
django-model-utils copied to clipboard
Django 3 with 4.0.0 causes stack overflow on cascade delete of tracker field models
Problem
When using 4.0.0 with Django 3.0.3 an stack overflow is caused when doing a queryset .delete() which causes a cascade delete of a model with a tracker field.
Environment
- Django Model Utils version: 4.0.0
- Django version: 3.0.3
- Python version: 3.6
- Other libraries used, if any: -
Stack trace
I don't have a separate code sandbox/test case, but for now here is a stack trace:
Keeps repeating:
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 1261 in _fetch_all
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 258 in __len__
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 411 in get
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 627 in refresh_from_db
File ".../lib/python3.6/site-packages/django/db/models/query_utils.py", line 139 in __get__
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 100 in get_field_value
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 126 in <dictcomp>
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 126 in current
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 106 in set_saved_fields
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 232 in initialize_tracker
File ".../lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 175 in <listcomp>
File ".../lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 175 in send
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 502 in __init__
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 512 in from_db
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 75 in __iter__
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 1261 in _fetch_all
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 258 in __len__
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 411 in get
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 627 in refresh_from_db
File ".../lib/python3.6/site-packages/django/db/models/query_utils.py", line 139 in __get__
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 100 in get_field_value
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 126 in <dictcomp>
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 126 in current
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 106 in set_saved_fields
File ".../lib/python3.6/site-packages/model_utils/tracker.py", line 232 in initialize_tracker
File ".../lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 175 in <listcomp>
File ".../lib/python3.6/site-packages/django/dispatch/dispatcher.py", line 175 in send
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 502 in __init__
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 512 in from_db
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 75 in __iter__
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 1261 in _fetch_all
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 258 in __len__
File ".../lib/python3.6/site-packages/django/db/models/query.py", line 411 in get
File ".../lib/python3.6/site-packages/django/db/models/base.py", line 627 in refresh_from_db
After some digging it appears this happens if you have a tracker on a ForeignKey field but you don't use the id. Django 3 then tries to initialise the field and you get into the infinite loop.
e.g. FieldTracker(fields="some_foreign_key_field")
gets into the above state but FieldTracker(fields="some_foreign_key_field_id")
does not
I noticed this in Django 4 as well
We narrowed field tracker down to only the fk field we needed to track with _id at the end of the field name.