Skip to content

FieldTracker not accessable during __init__() #640

Open
@soerenbe

Description

@soerenbe

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:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  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:

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)
[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 "<console>", line 1, in <module>
  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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions