Refs #20577 -- Deferred filtering of prefetched related querysets by reverse m2o relation.

This commit is contained in:
Bob Renwick 2020-10-06 10:04:11 +00:00 committed by Mariusz Felisiak
parent 999cddd58d
commit 036f160733
2 changed files with 13 additions and 9 deletions

View File

@ -581,6 +581,7 @@ def create_reverse_many_to_one_manager(superclass, rel):
queryset._add_hints(instance=self.instance)
if self._db:
queryset = queryset.using(self._db)
queryset._defer_next_filter = True
queryset = queryset.filter(**self.core_filters)
for field in self.field.foreign_related_fields:
val = getattr(self.instance, field.attname)

View File

@ -294,17 +294,20 @@ class PrefetchRelatedTests(TestDataMixin, TestCase):
def test_filter_deferred(self):
"""
Related filtering of prefetched querysets is deferred until necessary.
Related filtering of prefetched querysets is deferred on m2m and
reverse m2o relations until necessary.
"""
add_q = Query.add_q
with mock.patch.object(
Query,
'add_q',
autospec=True,
side_effect=lambda self, q: add_q(self, q),
) as add_q_mock:
list(Book.objects.prefetch_related('authors'))
self.assertEqual(add_q_mock.call_count, 1)
for relation in ['authors', 'first_time_authors']:
with self.subTest(relation=relation):
with mock.patch.object(
Query,
'add_q',
autospec=True,
side_effect=lambda self, q: add_q(self, q),
) as add_q_mock:
list(Book.objects.prefetch_related(relation))
self.assertEqual(add_q_mock.call_count, 1)
class RawQuerySetTests(TestDataMixin, TestCase):