diff --git a/django/db/models/options.py b/django/db/models/options.py index 83f1eb036a..0b669de121 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -535,7 +535,7 @@ class Options(object): except KeyError: # If the app registry is not ready, reverse fields are # unavailable, therefore we throw a FieldDoesNotExist exception. - if not self.apps.ready: + if not self.apps.models_ready: raise FieldDoesNotExist( "%s has no field named %r. The app cache isn't ready yet, " "so if this is an auto-created related field, it won't " diff --git a/tests/admin_checks/models.py b/tests/admin_checks/models.py index dbb5931c8c..835c26c0dc 100644 --- a/tests/admin_checks/models.py +++ b/tests/admin_checks/models.py @@ -49,6 +49,7 @@ class Book(models.Model): class AuthorsBooks(models.Model): author = models.ForeignKey(Author) book = models.ForeignKey(Book) + featured = models.BooleanField() class State(models.Model): diff --git a/tests/admin_checks/tests.py b/tests/admin_checks/tests.py index 3b12a35eb3..647a3d0eb4 100644 --- a/tests/admin_checks/tests.py +++ b/tests/admin_checks/tests.py @@ -688,3 +688,20 @@ class SystemChecksTestCase(TestCase): ) ] self.assertEqual(errors, expected) + + def test_list_filter_works_on_through_field_even_when_apps_not_ready(self): + """ + Ensure list_filter can access reverse fields even when the app registry + is not ready; refs #24146. + """ + class BookAdminWithListFilter(admin.ModelAdmin): + list_filter = ['authorsbooks__featured'] + + # Temporarily pretending apps are not ready yet. This issue can happen + # if the value of 'list_filter' refers to a 'through__field'. + Book._meta.apps.ready = False + try: + errors = BookAdminWithListFilter.check(model=Book) + self.assertEqual(errors, []) + finally: + Book._meta.apps.ready = True diff --git a/tests/model_meta/tests.py b/tests/model_meta/tests.py index 4a08b408c6..ef526b7bc4 100644 --- a/tests/model_meta/tests.py +++ b/tests/model_meta/tests.py @@ -178,7 +178,7 @@ class GetFieldByNameTests(OptionsBaseTests): opts = Person._meta # If apps registry is not ready, get_field() searches over only # forward fields. - opts.apps.ready = False + opts.apps.models_ready = False try: # 'data_abstract' is a forward field, and therefore will be found self.assertTrue(opts.get_field('data_abstract')) @@ -191,7 +191,7 @@ class GetFieldByNameTests(OptionsBaseTests): with self.assertRaisesMessage(FieldDoesNotExist, msg): opts.get_field('relating_baseperson') finally: - opts.apps.ready = True + opts.apps.models_ready = True class RelationTreeTests(TestCase):