diff options
| author | Nadège Michel <michel.nadege@gmail.com> | 2019-04-19 18:12:04 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2019-06-21 15:03:17 +0200 |
| commit | 87b1ad6e7351464c60e751b483d9dfce3a2d3382 (patch) | |
| tree | 24094846d09b2bc43429eb6c187c45b37a8bb2de /tests/m2m_recursive | |
| parent | a9179ab032cda80801e7f67ef20db5ee60989f21 (diff) | |
Fixed #30421 -- Allowed symmetrical intermediate table for self-referential ManyToManyField.
Diffstat (limited to 'tests/m2m_recursive')
| -rw-r--r-- | tests/m2m_recursive/models.py | 7 | ||||
| -rw-r--r-- | tests/m2m_recursive/tests.py | 58 |
2 files changed, 65 insertions, 0 deletions
diff --git a/tests/m2m_recursive/models.py b/tests/m2m_recursive/models.py index fd4f4ad166..a9f47770d6 100644 --- a/tests/m2m_recursive/models.py +++ b/tests/m2m_recursive/models.py @@ -22,7 +22,14 @@ from django.db import models class Person(models.Model): name = models.CharField(max_length=20) friends = models.ManyToManyField('self') + colleagues = models.ManyToManyField('self', symmetrical=True, through='Colleague') idols = models.ManyToManyField('self', symmetrical=False, related_name='stalkers') def __str__(self): return self.name + + +class Colleague(models.Model): + first = models.ForeignKey(Person, models.CASCADE) + second = models.ForeignKey(Person, models.CASCADE, related_name='+') + first_meet = models.DateField() diff --git a/tests/m2m_recursive/tests.py b/tests/m2m_recursive/tests.py index 0d992070a2..d0799f07d2 100644 --- a/tests/m2m_recursive/tests.py +++ b/tests/m2m_recursive/tests.py @@ -1,3 +1,5 @@ +import datetime + from django.test import TestCase from .models import Person @@ -59,3 +61,59 @@ class RecursiveM2MTests(TestCase): self.a.idols.add(self.a) self.assertSequenceEqual(self.a.idols.all(), [self.a]) self.assertSequenceEqual(self.a.stalkers.all(), [self.a]) + + +class RecursiveSymmetricalM2MThroughTests(TestCase): + @classmethod + def setUpTestData(cls): + cls.a, cls.b, cls.c, cls.d = [ + Person.objects.create(name=name) + for name in ['Anne', 'Bill', 'Chuck', 'David'] + ] + cls.a.colleagues.add(cls.b, cls.c, through_defaults={ + 'first_meet': datetime.date(2013, 1, 5), + }) + # Add m2m for Anne and Chuck in reverse direction. + cls.d.colleagues.add(cls.a, cls.c, through_defaults={ + 'first_meet': datetime.date(2015, 6, 15), + }) + + def test_recursive_m2m_all(self): + for person, colleagues in ( + (self.a, [self.b, self.c, self.d]), + (self.b, [self.a]), + (self.c, [self.a, self.d]), + (self.d, [self.a, self.c]), + ): + with self.subTest(person=person): + self.assertSequenceEqual(person.colleagues.all(), colleagues) + + def test_recursive_m2m_reverse_add(self): + # Add m2m for Anne in reverse direction. + self.b.colleagues.add(self.a, through_defaults={ + 'first_meet': datetime.date(2013, 1, 5), + }) + self.assertSequenceEqual(self.a.colleagues.all(), [self.b, self.c, self.d]) + self.assertSequenceEqual(self.b.colleagues.all(), [self.a]) + + def test_recursive_m2m_remove(self): + self.b.colleagues.remove(self.a) + self.assertSequenceEqual(self.a.colleagues.all(), [self.c, self.d]) + self.assertSequenceEqual(self.b.colleagues.all(), []) + + def test_recursive_m2m_clear(self): + # Clear m2m for Anne. + self.a.colleagues.clear() + self.assertSequenceEqual(self.a.friends.all(), []) + # Reverse m2m relationships is removed. + self.assertSequenceEqual(self.c.colleagues.all(), [self.d]) + self.assertSequenceEqual(self.d.colleagues.all(), [self.c]) + + def test_recursive_m2m_set(self): + # Set new relationships for Chuck. + self.c.colleagues.set([self.b, self.d], through_defaults={ + 'first_meet': datetime.date(2013, 1, 5), + }) + self.assertSequenceEqual(self.c.colleagues.order_by('name'), [self.b, self.d]) + # Reverse m2m relationships is removed. + self.assertSequenceEqual(self.a.colleagues.order_by('name'), [self.b, self.d]) |
