Fixed #28723 -- Fixed RelatedManager's prefetch_related() cache name.

This commit is contained in:
Mike Hansen 2017-10-18 12:05:08 -07:00 committed by Tim Graham
parent ef718a72b3
commit 514b2c989a
2 changed files with 13 additions and 3 deletions

View File

@ -581,7 +581,7 @@ def create_reverse_many_to_one_manager(superclass, rel):
def get_queryset(self): def get_queryset(self):
try: try:
return self.instance._prefetched_objects_cache[self.field.related_query_name()] return self.instance._prefetched_objects_cache[self.field.remote_field.get_cache_name()]
except (AttributeError, KeyError): except (AttributeError, KeyError):
queryset = super().get_queryset() queryset = super().get_queryset()
return self._apply_rel_filters(queryset) return self._apply_rel_filters(queryset)
@ -604,7 +604,7 @@ def create_reverse_many_to_one_manager(superclass, rel):
for rel_obj in queryset: for rel_obj in queryset:
instance = instances_dict[rel_obj_attr(rel_obj)] instance = instances_dict[rel_obj_attr(rel_obj)]
setattr(rel_obj, self.field.name, instance) setattr(rel_obj, self.field.name, instance)
cache_name = self.field.related_query_name() cache_name = self.field.remote_field.get_cache_name()
return queryset, rel_obj_attr, instance_attr, False, cache_name, False return queryset, rel_obj_attr, instance_attr, False, cache_name, False
def add(self, *objs, bulk=True): def add(self, *objs, bulk=True):

View File

@ -2,7 +2,7 @@ from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import connection from django.db import connection
from django.db.models import Prefetch, QuerySet from django.db.models import Prefetch, QuerySet
from django.db.models.query import get_prefetcher from django.db.models.query import get_prefetcher, prefetch_related_objects
from django.test import TestCase, override_settings from django.test import TestCase, override_settings
from django.test.utils import CaptureQueriesContext from django.test.utils import CaptureQueriesContext
@ -1329,6 +1329,8 @@ class DirectPrefechedObjectCacheReuseTests(TestCase):
AuthorAddress.objects.create(author=cls.author12, address='Haunted house'), AuthorAddress.objects.create(author=cls.author12, address='Haunted house'),
AuthorAddress.objects.create(author=cls.author21, address='Happy place'), AuthorAddress.objects.create(author=cls.author21, address='Happy place'),
] ]
cls.bookwithyear1 = BookWithYear.objects.create(title='Poems', published_year=2010)
cls.bookreview1 = BookReview.objects.create(book=cls.bookwithyear1)
def test_detect_is_fetched(self): def test_detect_is_fetched(self):
""" """
@ -1405,6 +1407,14 @@ class DirectPrefechedObjectCacheReuseTests(TestCase):
self.assertEqual(book1.first_authors[1].happy_place, []) self.assertEqual(book1.first_authors[1].happy_place, [])
self.assertEqual(book2.first_authors[0].happy_place, [self.author2_address1]) self.assertEqual(book2.first_authors[0].happy_place, [self.author2_address1])
def test_prefetch_reverse_foreign_key(self):
with self.assertNumQueries(2):
bookwithyear1, = BookWithYear.objects.prefetch_related('bookreview_set')
with self.assertNumQueries(0):
self.assertCountEqual(bookwithyear1.bookreview_set.all(), [self.bookreview1])
with self.assertNumQueries(0):
prefetch_related_objects([bookwithyear1], 'bookreview_set')
class ReadPrefetchedObjectsCacheTests(TestCase): class ReadPrefetchedObjectsCacheTests(TestCase):
@classmethod @classmethod