diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index 2927e66f83..d3e2098a67 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -476,6 +476,8 @@ class ProjectState: def _find_concrete_model_from_proxy(self, proxy_models, model_state): for base in model_state.bases: + if not (isinstance(base, str) or issubclass(base, models.Model)): + continue base_key = make_model_tuple(base) base_state = proxy_models.get(base_key) if not base_state: diff --git a/tests/migrations/test_autodetector.py b/tests/migrations/test_autodetector.py index 8e3382adb9..3b46601145 100644 --- a/tests/migrations/test_autodetector.py +++ b/tests/migrations/test_autodetector.py @@ -1783,6 +1783,29 @@ class AutodetectorTests(TestCase): self.assertOperationAttributes(changes, "testapp", 0, 0, name="AuthorProxy") self.assertOperationAttributes(changes, "testapp", 0, 1, name="AuthorProxy", options={}) + def test_proxy_non_model_parent(self): + class Mixin: + pass + + author_proxy_non_model_parent = ModelState( + 'testapp', + 'AuthorProxy', + [], + {'proxy': True}, + (Mixin, 'testapp.author'), + ) + changes = self.get_changes( + [self.author_empty], + [self.author_empty, author_proxy_non_model_parent], + ) + self.assertNumberMigrations(changes, 'testapp', 1) + self.assertOperationTypes(changes, 'testapp', 0, ['CreateModel']) + self.assertOperationAttributes( + changes, 'testapp', 0, 0, name='AuthorProxy', + options={'proxy': True, 'indexes': [], 'constraints': []}, + bases=(Mixin, 'testapp.author'), + ) + def test_proxy_custom_pk(self): """ #23415 - The autodetector must correctly deal with custom FK on proxy