diff options
author | Collin Anderson <cmawebsite@gmail.com> | 2017-03-20 20:26:23 -0400 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2019-01-15 11:12:17 -0500 |
commit | 769355c76531749d0bc0abad279402e361eaec4e (patch) | |
tree | 2f9600d8779a41ebb44abde07485cea472227018 /tests/m2m_through | |
parent | f021c110d02fd7ca32ae56f511b46e5d138b6c73 (diff) | |
download | django-769355c76531749d0bc0abad279402e361eaec4e.tar.gz |
Fixed #9475 -- Allowed RelatedManager.add(), create(), etc. for m2m with a through model.
Diffstat (limited to 'tests/m2m_through')
-rw-r--r-- | tests/m2m_through/models.py | 2 | ||||
-rw-r--r-- | tests/m2m_through/tests.py | 146 |
2 files changed, 72 insertions, 76 deletions
diff --git a/tests/m2m_through/models.py b/tests/m2m_through/models.py index a84608a530..141d02daf8 100644 --- a/tests/m2m_through/models.py +++ b/tests/m2m_through/models.py @@ -66,7 +66,7 @@ class CustomMembership(models.Model): class TestNoDefaultsOrNulls(models.Model): person = models.ForeignKey(Person, models.CASCADE) group = models.ForeignKey(Group, models.CASCADE) - nodefaultnonull = models.CharField(max_length=5) + nodefaultnonull = models.IntegerField() class PersonSelfRefM2M(models.Model): diff --git a/tests/m2m_through/tests.py b/tests/m2m_through/tests.py index 930f5e848c..2921a1a260 100644 --- a/tests/m2m_through/tests.py +++ b/tests/m2m_through/tests.py @@ -1,6 +1,7 @@ from datetime import datetime from operator import attrgetter +from django.db import IntegrityError from django.test import TestCase from .models import ( @@ -56,52 +57,76 @@ class M2mThroughTests(TestCase): expected ) - def test_cannot_use_add_on_m2m_with_intermediary_model(self): - msg = 'Cannot use add() on a ManyToManyField which specifies an intermediary model' + def test_add_on_m2m_with_intermediate_model(self): + self.rock.members.add(self.bob, through_defaults={'invite_reason': 'He is good.'}) + self.assertSequenceEqual(self.rock.members.all(), [self.bob]) + self.assertEqual(self.rock.membership_set.get().invite_reason, 'He is good.') - with self.assertRaisesMessage(AttributeError, msg): - self.rock.members.add(self.bob) + def test_add_on_m2m_with_intermediate_model_value_required(self): + self.rock.nodefaultsnonulls.add(self.jim, through_defaults={'nodefaultnonull': 1}) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 1) - self.assertQuerysetEqual( - self.rock.members.all(), - [] - ) + def test_add_on_m2m_with_intermediate_model_value_required_fails(self): + with self.assertRaises(IntegrityError): + self.rock.nodefaultsnonulls.add(self.jim) - def test_cannot_use_create_on_m2m_with_intermediary_model(self): - msg = 'Cannot use create() on a ManyToManyField which specifies an intermediary model' + def test_create_on_m2m_with_intermediate_model(self): + annie = self.rock.members.create(name='Annie', through_defaults={'invite_reason': 'She was just awesome.'}) + self.assertSequenceEqual(self.rock.members.all(), [annie]) + self.assertEqual(self.rock.membership_set.get().invite_reason, 'She was just awesome.') - with self.assertRaisesMessage(AttributeError, msg): - self.rock.members.create(name='Annie') + def test_create_on_m2m_with_intermediate_model_value_required(self): + self.rock.nodefaultsnonulls.create(name='Test', through_defaults={'nodefaultnonull': 1}) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 1) - self.assertQuerysetEqual( - self.rock.members.all(), - [] - ) + def test_create_on_m2m_with_intermediate_model_value_required_fails(self): + with self.assertRaises(IntegrityError): + self.rock.nodefaultsnonulls.create(name='Test') - def test_cannot_use_remove_on_m2m_with_intermediary_model(self): - Membership.objects.create(person=self.jim, group=self.rock) - msg = 'Cannot use remove() on a ManyToManyField which specifies an intermediary model' + def test_get_or_create_on_m2m_with_intermediate_model_value_required(self): + self.rock.nodefaultsnonulls.get_or_create(name='Test', through_defaults={'nodefaultnonull': 1}) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 1) - with self.assertRaisesMessage(AttributeError, msg): - self.rock.members.remove(self.jim) + def test_get_or_create_on_m2m_with_intermediate_model_value_required_fails(self): + with self.assertRaises(IntegrityError): + self.rock.nodefaultsnonulls.get_or_create(name='Test') - self.assertQuerysetEqual( - self.rock.members.all(), - ['Jim'], - attrgetter("name") - ) + def test_update_or_create_on_m2m_with_intermediate_model_value_required(self): + self.rock.nodefaultsnonulls.update_or_create(name='Test', through_defaults={'nodefaultnonull': 1}) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 1) + + def test_update_or_create_on_m2m_with_intermediate_model_value_required_fails(self): + with self.assertRaises(IntegrityError): + self.rock.nodefaultsnonulls.update_or_create(name='Test') + + def test_remove_on_m2m_with_intermediate_model(self): + Membership.objects.create(person=self.jim, group=self.rock) + self.rock.members.remove(self.jim) + self.assertSequenceEqual(self.rock.members.all(), []) - def test_cannot_use_setattr_on_m2m_with_intermediary_model(self): - msg = 'Cannot set values on a ManyToManyField which specifies an intermediary model' + def test_remove_on_m2m_with_intermediate_model_multiple(self): + Membership.objects.create(person=self.jim, group=self.rock, invite_reason='1') + Membership.objects.create(person=self.jim, group=self.rock, invite_reason='2') + self.assertSequenceEqual(self.rock.members.all(), [self.jim, self.jim]) + self.rock.members.remove(self.jim) + self.assertSequenceEqual(self.rock.members.all(), []) + + def test_set_on_m2m_with_intermediate_model(self): members = list(Person.objects.filter(name__in=['Bob', 'Jim'])) + self.rock.members.set(members) + self.assertSequenceEqual(self.rock.members.all(), [self.bob, self.jim]) - with self.assertRaisesMessage(AttributeError, msg): - self.rock.members.set(members) + def test_set_on_m2m_with_intermediate_model_value_required(self): + self.rock.nodefaultsnonulls.set([self.jim], through_defaults={'nodefaultnonull': 1}) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 1) + self.rock.nodefaultsnonulls.set([self.jim], through_defaults={'nodefaultnonull': 2}) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 1) + self.rock.nodefaultsnonulls.set([self.jim], through_defaults={'nodefaultnonull': 2}, clear=True) + self.assertEqual(self.rock.testnodefaultsornulls_set.get().nodefaultnonull, 2) - self.assertQuerysetEqual( - self.rock.members.all(), - [] - ) + def test_set_on_m2m_with_intermediate_model_value_required_fails(self): + with self.assertRaises(IntegrityError): + self.rock.nodefaultsnonulls.set([self.jim]) def test_clear_removes_all_the_m2m_relationships(self): Membership.objects.create(person=self.jim, group=self.rock) @@ -125,52 +150,23 @@ class M2mThroughTests(TestCase): attrgetter("name") ) - def test_cannot_use_add_on_reverse_m2m_with_intermediary_model(self): - msg = 'Cannot use add() on a ManyToManyField which specifies an intermediary model' + def test_add_on_reverse_m2m_with_intermediate_model(self): + self.bob.group_set.add(self.rock) + self.assertSequenceEqual(self.bob.group_set.all(), [self.rock]) - with self.assertRaisesMessage(AttributeError, msg): - self.bob.group_set.add(self.bob) + def test_create_on_reverse_m2m_with_intermediate_model(self): + funk = self.bob.group_set.create(name='Funk') + self.assertSequenceEqual(self.bob.group_set.all(), [funk]) - self.assertQuerysetEqual( - self.bob.group_set.all(), - [] - ) - - def test_cannot_use_create_on_reverse_m2m_with_intermediary_model(self): - msg = 'Cannot use create() on a ManyToManyField which specifies an intermediary model' - - with self.assertRaisesMessage(AttributeError, msg): - self.bob.group_set.create(name='Funk') - - self.assertQuerysetEqual( - self.bob.group_set.all(), - [] - ) - - def test_cannot_use_remove_on_reverse_m2m_with_intermediary_model(self): + def test_remove_on_reverse_m2m_with_intermediate_model(self): Membership.objects.create(person=self.bob, group=self.rock) - msg = 'Cannot use remove() on a ManyToManyField which specifies an intermediary model' - - with self.assertRaisesMessage(AttributeError, msg): - self.bob.group_set.remove(self.rock) + self.bob.group_set.remove(self.rock) + self.assertSequenceEqual(self.bob.group_set.all(), []) - self.assertQuerysetEqual( - self.bob.group_set.all(), - ['Rock'], - attrgetter('name') - ) - - def test_cannot_use_setattr_on_reverse_m2m_with_intermediary_model(self): - msg = 'Cannot set values on a ManyToManyField which specifies an intermediary model' + def test_set_on_reverse_m2m_with_intermediate_model(self): members = list(Group.objects.filter(name__in=['Rock', 'Roll'])) - - with self.assertRaisesMessage(AttributeError, msg): - self.bob.group_set.set(members) - - self.assertQuerysetEqual( - self.bob.group_set.all(), - [] - ) + self.bob.group_set.set(members) + self.assertSequenceEqual(self.bob.group_set.all(), [self.rock, self.roll]) def test_clear_on_reverse_removes_all_the_m2m_relationships(self): Membership.objects.create(person=self.jim, group=self.rock) |