summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2016-12-28 11:44:26 -0500
committerTim Graham <timograham@gmail.com>2016-12-28 12:48:17 -0500
commite3e80da7a59f6fcef814b951f5a77a33584e3b62 (patch)
treeebb37d8cf13594d502406d68cd2967c754f0b233
parentaaecf038cae61f114db396f74e06759c95f21e93 (diff)
Fixed #27651 -- Allowed M2M to concrete and proxy through model.
-rw-r--r--django/db/models/fields/related.py6
-rw-r--r--tests/invalid_models_tests/test_models.py18
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):