Refs #19544 -- Added a fast path for through additions if supported.

The single query insertion path is taken if the backend supports inserts
that ignore conflicts and m2m_changed signals don't have to be sent.
This commit is contained in:
Simon Charette 2019-02-15 22:02:33 -05:00 committed by Tim Graham
parent 28712d8acf
commit de7f6b51b2
2 changed files with 71 additions and 20 deletions

View file

@ -118,13 +118,26 @@ class ManyToManyTests(TestCase):
)
@skipUnlessDBFeature('supports_ignore_conflicts')
def test_add_ignore_conflicts(self):
def test_fast_add_ignore_conflicts(self):
"""
A single query is necessary to add auto-created through instances if
the database backend supports bulk_create(ignore_conflicts) and no
m2m_changed signals receivers are connected.
"""
with self.assertNumQueries(1):
self.a1.publications.add(self.p1, self.p2)
@skipUnlessDBFeature('supports_ignore_conflicts')
def test_slow_add_ignore_conflicts(self):
manager_cls = self.a1.publications.__class__
# Simulate a race condition between the missing ids retrieval and
# the bulk insertion attempt.
missing_target_ids = {self.p1.id}
# Disable fast-add to test the case where the slow add path is taken.
add_plan = (True, False, False)
with mock.patch.object(manager_cls, '_get_missing_target_ids', return_value=missing_target_ids) as mocked:
self.a1.publications.add(self.p1)
with mock.patch.object(manager_cls, '_get_add_plan', return_value=add_plan):
self.a1.publications.add(self.p1)
mocked.assert_called_once()
def test_related_sets(self):