diff options
| author | Tim Graham <timograham@gmail.com> | 2016-12-28 11:44:26 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-12-28 12:48:17 -0500 |
| commit | e3e80da7a59f6fcef814b951f5a77a33584e3b62 (patch) | |
| tree | ebb37d8cf13594d502406d68cd2967c754f0b233 | |
| parent | aaecf038cae61f114db396f74e06759c95f21e93 (diff) | |
Fixed #27651 -- Allowed M2M to concrete and proxy through model.
| -rw-r--r-- | django/db/models/fields/related.py | 6 | ||||
| -rw-r--r-- | tests/invalid_models_tests/test_models.py | 18 |
2 files changed, 22 insertions, 2 deletions
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 3ba957f2d4..10ba7696ca 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1447,8 +1447,10 @@ class ManyToManyField(RelatedField): if model != self.remote_field.through and model._meta.managed } m2m_db_table = self.m2m_db_table() - if m2m_db_table in registered_tables: - model = registered_tables[m2m_db_table] + model = registered_tables.get(m2m_db_table) + # The second condition allows multiple m2m relations on a model if + # some point to a through model that proxies another through model. + if model and model._meta.concrete_model != self.remote_field.through._meta.concrete_model: if model._meta.auto_created: def _get_field_name(model): for field in model._meta.auto_created._meta.many_to_many: diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index b50b265bd4..78f2164ed5 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -899,6 +899,24 @@ class OtherModelTests(SimpleTestCase): self.assertEqual(C1.check(), []) self.assertEqual(C2.check(), []) + def test_m2m_to_concrete_and_proxy_allowed(self): + class A(models.Model): + pass + + class Through(models.Model): + a = models.ForeignKey('A', models.CASCADE) + c = models.ForeignKey('C', models.CASCADE) + + class ThroughProxy(Through): + class Meta: + proxy = True + + class C(models.Model): + mm_a = models.ManyToManyField(A, through=Through) + mm_aproxy = models.ManyToManyField(A, through=ThroughProxy, related_name='proxied_m2m') + + self.assertEqual(C.check(), []) + @isolate_apps('django.contrib.auth', kwarg_name='apps') def test_lazy_reference_checks(self, apps): class DummyModel(models.Model): |
