diff options
author | InvalidInterrupt <InvalidInterrupt@users.noreply.github.com> | 2016-08-18 15:42:11 -0700 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2016-12-07 17:50:51 -0500 |
commit | 98359109eb0ed68a5821476bcd797455723aaaba (patch) | |
tree | f54f4fd3acffe5551873b4d00faab512a9e583d5 /tests/m2m_through_regress | |
parent | b5f0b3478dfcf0335f8ac2038d59f54b4a05f2a0 (diff) | |
download | django-98359109eb0ed68a5821476bcd797455723aaaba.tar.gz |
Fixed #17002 -- Allowed using a ManyToManyField through model that inherits another.
Diffstat (limited to 'tests/m2m_through_regress')
-rw-r--r-- | tests/m2m_through_regress/models.py | 29 | ||||
-rw-r--r-- | tests/m2m_through_regress/test_multitable.py | 51 |
2 files changed, 80 insertions, 0 deletions
diff --git a/tests/m2m_through_regress/models.py b/tests/m2m_through_regress/models.py index 10dcddfc58..adde24dcf9 100644 --- a/tests/m2m_through_regress/models.py +++ b/tests/m2m_through_regress/models.py @@ -94,3 +94,32 @@ class CarDriver(models.Model): def __str__(self): return "pk=%s car=%s driver=%s" % (str(self.pk), self.car, self.driver) + + +# Through models using multi-table inheritance +class Event(models.Model): + name = models.CharField(max_length=50, unique=True) + people = models.ManyToManyField('Person', through='IndividualCompetitor') + special_people = models.ManyToManyField( + 'Person', + through='ProxiedIndividualCompetitor', + related_name='special_event_set', + ) + teams = models.ManyToManyField('Group', through='CompetingTeam') + + +class Competitor(models.Model): + event = models.ForeignKey(Event, models.CASCADE) + + +class IndividualCompetitor(Competitor): + person = models.ForeignKey(Person, models.CASCADE) + + +class CompetingTeam(Competitor): + team = models.ForeignKey(Group, models.CASCADE) + + +class ProxiedIndividualCompetitor(IndividualCompetitor): + class Meta: + proxy = True diff --git a/tests/m2m_through_regress/test_multitable.py b/tests/m2m_through_regress/test_multitable.py new file mode 100644 index 0000000000..f07af40f6d --- /dev/null +++ b/tests/m2m_through_regress/test_multitable.py @@ -0,0 +1,51 @@ +from __future__ import unicode_literals + +from django.test import TestCase + +from .models import ( + CompetingTeam, Event, Group, IndividualCompetitor, Membership, Person, +) + + +class MultiTableTests(TestCase): + @classmethod + def setUpTestData(cls): + cls.alice = Person.objects.create(name='Alice') + cls.bob = Person.objects.create(name='Bob') + cls.chris = Person.objects.create(name='Chris') + cls.dan = Person.objects.create(name='Dan') + cls.team_alpha = Group.objects.create(name='Alpha') + Membership.objects.create(person=cls.alice, group=cls.team_alpha) + Membership.objects.create(person=cls.bob, group=cls.team_alpha) + cls.event = Event.objects.create(name='Exposition Match') + IndividualCompetitor.objects.create(event=cls.event, person=cls.chris) + IndividualCompetitor.objects.create(event=cls.event, person=cls.dan) + CompetingTeam.objects.create(event=cls.event, team=cls.team_alpha) + + def test_m2m_query(self): + result = self.event.teams.all() + self.assertCountEqual(result, [self.team_alpha]) + + def test_m2m_reverse_query(self): + result = self.chris.event_set.all() + self.assertCountEqual(result, [self.event]) + + def test_m2m_query_proxied(self): + result = self.event.special_people.all() + self.assertCountEqual(result, [self.chris, self.dan]) + + def test_m2m_reverse_query_proxied(self): + result = self.chris.special_event_set.all() + self.assertCountEqual(result, [self.event]) + + def test_m2m_prefetch_proxied(self): + result = Event.objects.filter(name='Exposition Match').prefetch_related('special_people') + with self.assertNumQueries(2): + self.assertCountEqual(result, [self.event]) + self.assertEqual(sorted([p.name for p in result[0].special_people.all()]), ['Chris', 'Dan']) + + def test_m2m_prefetch_reverse_proxied(self): + result = Person.objects.filter(name='Dan').prefetch_related('special_event_set') + with self.assertNumQueries(2): + self.assertCountEqual(result, [self.dan]) + self.assertEqual([event.name for event in result[0].special_event_set.all()], ['Exposition Match']) |