﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
36713	RecursionError with only() and fields usage in __init__	Michal Čihař		"Django ends up in infinite recursion when combining `only()` and accessing class attributes in `__init__`:

{{{
  File ""/tmp/django-recursion-test/app/models.py"", line 14, in __init__
    print(self.descriptions)
          ^^^^^^^^^^^^^^^^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query_utils.py"", line 267, in __get__
    instance.refresh_from_db(fields=[field_name])
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/base.py"", line 758, in refresh_from_db
    db_instance = db_instance_qs.get()
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 633, in get
    num = len(clone)
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 370, in __len__
    self._fetch_all()
    ~~~~~~~~~~~~~~~^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 1995, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 126, in __iter__
    obj = model_cls.from_db(
        db, init_list, row[model_fields_start:model_fields_end]
    )
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/base.py"", line 605, in from_db
    new = cls(*values)
  File ""/tmp/django-recursion-test/app/models.py"", line 15, in __init__
    print(self.notes)
          ^^^^^^^^^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query_utils.py"", line 267, in __get__
    instance.refresh_from_db(fields=[field_name])
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/base.py"", line 758, in refresh_from_db
    db_instance = db_instance_qs.get()
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 633, in get
    num = len(clone)
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 370, in __len__
    self._fetch_all()
    ~~~~~~~~~~~~~~~^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 1995, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/query.py"", line 126, in __iter__
    obj = model_cls.from_db(
        db, init_list, row[model_fields_start:model_fields_end]
    )
  File ""/tmp/django-test/lib/python3.13/site-packages/django/db/models/base.py"", line 605, in from_db
    new = cls(*values)
  File ""/tmp/django-recursion-test/app/models.py"", line 14, in __init__
    print(self.descriptions)
          ^^^^^^^^^^^^^^^^^
}}}

Preconditions for the error:

* Model with multiple fields
* Using at least two model fields in `__init__` (it does work fine with accessing just one)
* Using `only()` with fields used in `__init__` but missing a field that will be used later

To trigger this error, following model was used:

{{{
class Project(models.Model):
    name = models.CharField(max_length=100)
    slug = models.CharField(max_length=100)
    descriptions = models.TextField()
    notes = models.TextField()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        print(self.descriptions)
        print(self.notes)
}}}

And this is the code to trigger it:

{{{
        Project.objects.create(name=""Test"", slug=""test"")
        projects = Project.objects.only(""descriptions"", ""notes"")
        # object is constructed and the field included only can be accessed:
        self.assertEqual(projects[0].notes, """")
        # this fails with RecursionError
        self.assertEqual(projects[0].slug, ""test"")
}}}

Reproduced with both Django 5.2 and 6.0b1.

Reproducing tests are available at https://github.com/nijel/django-recursion-test."	Uncategorized	closed	Uncategorized	5.2	Normal	invalid			Unreviewed	0	0	0	0	0	0
