summaryrefslogtreecommitdiff
path: root/tests/m2m_through
diff options
context:
space:
mode:
authorCollin Anderson <cmawebsite@gmail.com>2017-03-20 20:26:23 -0400
committerTim Graham <timograham@gmail.com>2019-01-15 11:12:17 -0500
commit769355c76531749d0bc0abad279402e361eaec4e (patch)
tree2f9600d8779a41ebb44abde07485cea472227018 /tests/m2m_through
parentf021c110d02fd7ca32ae56f511b46e5d138b6c73 (diff)
downloaddjango-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.py2
-rw-r--r--tests/m2m_through/tests.py146
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)