mirror of https://github.com/django/django.git
Fixed #28834 -- Followed ancestor links on field cache lookup failure.
Thanks Tim for the review.
This commit is contained in:
parent
746caf3ef8
commit
78c5e7b90e
|
@ -12,6 +12,22 @@ class FieldCacheMixin:
|
|||
try:
|
||||
return instance._state.fields_cache[cache_name]
|
||||
except KeyError:
|
||||
# An ancestor link will exist if this field is defined on a
|
||||
# multi-table inheritance parent of the instance's class.
|
||||
ancestor_link = instance._meta.get_ancestor_link(self.model)
|
||||
if ancestor_link:
|
||||
try:
|
||||
# The value might be cached on an ancestor if the instance
|
||||
# originated from walking down the inheritance chain.
|
||||
ancestor = ancestor_link.get_cached_value(instance)
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
value = self.get_cached_value(ancestor)
|
||||
# Cache the ancestor value locally to speed up future
|
||||
# lookups.
|
||||
self.set_cached_value(instance, value)
|
||||
return value
|
||||
if default is NOT_PROVIDED:
|
||||
raise
|
||||
return default
|
||||
|
|
|
@ -178,6 +178,7 @@ class GrandParent(models.Model):
|
|||
first_name = models.CharField(max_length=80)
|
||||
last_name = models.CharField(max_length=80)
|
||||
email = models.EmailField(unique=True)
|
||||
place = models.ForeignKey(Place, models.CASCADE, null=True, related_name='+')
|
||||
|
||||
class Meta:
|
||||
unique_together = ('first_name', 'last_name')
|
||||
|
|
|
@ -368,6 +368,22 @@ class ModelInheritanceDataTests(TestCase):
|
|||
self.assertEqual(qs[1].italianrestaurant.name, 'Ristorante Miron')
|
||||
self.assertEqual(qs[1].italianrestaurant.rating, 4)
|
||||
|
||||
def test_parent_cache_reuse(self):
|
||||
place = Place.objects.create()
|
||||
GrandChild.objects.create(place=place)
|
||||
grand_parent = GrandParent.objects.latest('pk')
|
||||
with self.assertNumQueries(1):
|
||||
self.assertEqual(grand_parent.place, place)
|
||||
parent = grand_parent.parent
|
||||
with self.assertNumQueries(0):
|
||||
self.assertEqual(parent.place, place)
|
||||
child = parent.child
|
||||
with self.assertNumQueries(0):
|
||||
self.assertEqual(child.place, place)
|
||||
grandchild = child.grandchild
|
||||
with self.assertNumQueries(0):
|
||||
self.assertEqual(grandchild.place, place)
|
||||
|
||||
def test_update_query_counts(self):
|
||||
"""
|
||||
Update queries do not generate unnecessary queries (#18304).
|
||||
|
|
|
@ -82,7 +82,7 @@ class ReverseSelectRelatedTestCase(TestCase):
|
|||
stat = UserStat.objects.select_related('user', 'advanceduserstat').get(posts=200)
|
||||
self.assertEqual(stat.advanceduserstat.posts, 200)
|
||||
self.assertEqual(stat.user.username, 'bob')
|
||||
with self.assertNumQueries(1):
|
||||
with self.assertNumQueries(0):
|
||||
self.assertEqual(stat.advanceduserstat.user.username, 'bob')
|
||||
|
||||
def test_nullable_relation(self):
|
||||
|
|
Loading…
Reference in New Issue