diff --git a/django/db/models/base.py b/django/db/models/base.py index 2444c22b01..80d98b1399 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -1687,6 +1687,10 @@ class Model(six.with_metaclass(ModelBase)): ) for f in cls._meta.local_many_to_many: + # Skip nonexistent models. + if isinstance(f.remote_field.through, six.string_types): + continue + # Check if auto-generated name for the M2M field is too long # for the database. for m2m in f.remote_field.through._meta.local_fields: diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index b681e35587..96d3f7815f 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -307,6 +307,22 @@ class RelativeFieldTests(SimpleTestCase): ] self.assertEqual(errors, expected) + def test_missing_relationship_model_on_model_check(self): + class Person(models.Model): + pass + + class Group(models.Model): + members = models.ManyToManyField('Person', through='MissingM2MModel') + + self.assertEqual(Group.check(), [ + Error( + "Field specifies a many-to-many relation through model " + "'MissingM2MModel', which has not been installed.", + obj=Group._meta.get_field('members'), + id='fields.E331', + ), + ]) + @isolate_apps('invalid_models_tests') def test_many_to_many_through_isolate_apps_model(self): """