jazzband / jazzband/django-model-utils
FieldTracker not accessable during __init__()
- Dominant language
- Python
- Stars
- 2.8k
- Forks
- 375
- PR merge metrics
- No merged PRs in 30d
Description
We run into strange error when updating out `django-model-utils` to >= 4.5.1. I could reproduce this error with `django-model-utils` 4.5.1 and 5.0.0
The error stated like that during:
```python
Traceback (most recent call last):
File "", line 1, in
File "/home/user/tmp/tmp/.venv/lib/python3.12/site-packages/model_utils/tracker.py", line 402, in inner
original(instance, *args, **kwargs)
File "/home/user/tmp/tmp/proj/app/models.py", line 11, in __init__
print(self.tracker)
^^^^^^^^^^^^
File "/home/user/tmp/tmp/.venv/lib/python3.12/site-packages/model_utils/tracker.py", line 442, in __get__
return getattr(instance, self.attname)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'TestModel' object has no attribute '_tracker'. Did you mean: 'tracker'?
```
Our model accesses the tracker during `__init__` to verify it is setup correctly, since the Tracker is defined in an abstract class.
After some investigation I found out, that you can not access the tracker during `__init__`, since it seems relay on data generated by Django's `contribute_to_class`, but it gets a little nebulous for me there at this point.
I have compiled a minimal Model zu reproduce the error. It can be used in a new django project to reproduce the error:
```python3
from django.db import models
from model_utils import FieldTracker
class TestModel(models.Model):
comment = models.CharField()
tracker = FieldTracker()
# When removing this everything is fine
def __init__(self, *args, **kwargs):
print(self.tracker)
```
```bash
[user@host ] ~/tmp/tmp/proj$ poetry run python3 manage.py shell
7 objects imported automatically (use -v 2 for details).
Python 3.12.3 (main, Feb 4 2025, 14:48:35) [GCC 13.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app.models import TestModel
>>> x=TestModel()
Traceback (most recent call last):
File "", line 1, in
File "/home/sob/tmp/tmp/.venv/lib/python3.12/site-packages/model_utils/tracker.py", line 402, in inner
original(instance, *args, **kwargs)
File "/home/sob/tmp/tmp/proj/app/models.py", line 11, in __init__
print(self.tracker)
^^^^^^^^^^^^
File "/home/sob/tmp/tmp/.venv/lib/python3.12/site-packages/model_utils/tracker.py", line 442, in __get__
return getattr(instance, self.attname)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'TestModel' object has no attribute '_tracker'. Did you mean: 'tracker'?
>>>
```
Our current workaround is to check the tracker in `__new__()`, but this is not obvious and may not match any usecase.
I understand that the `FieldTracker` do some tricky stuff to achieve its feature. When a fix is not possible a hint in the documentation may be a good starting point.
Contributor guide
Research direction
Start with the minimal TestModel in app/models.py and reproduce the failure while reading the FieldTracker behavior shown in model_utils/tracker.py. Determine whether tracker access during __init__ should be supported or documented as unavailable. Done means the behavior is corrected or clearly documented, with coverage for the reported initialization case if a fix is made.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- django, python
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100