From 265506bbc347a6b3fcc6c66ab1a2417b3b7ea57a Mon Sep 17 00:00:00 2001 From: Paulo Date: Mon, 14 May 2018 11:01:53 -0400 Subject: [PATCH] Refs #28834 -- Moved ancestor field cached value fallback to related fields descriptor. --- django/db/models/fields/mixins.py | 16 ---------------- django/db/models/fields/related_descriptors.py | 14 +++++++++++--- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/django/db/models/fields/mixins.py b/django/db/models/fields/mixins.py index f79b7b0c6e..c6dbc4ec5e 100644 --- a/django/db/models/fields/mixins.py +++ b/django/db/models/fields/mixins.py @@ -12,22 +12,6 @@ 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 diff --git a/django/db/models/fields/related_descriptors.py b/django/db/models/fields/related_descriptors.py index 850ea99fa1..4ae4bf5156 100644 --- a/django/db/models/fields/related_descriptors.py +++ b/django/db/models/fields/related_descriptors.py @@ -162,10 +162,18 @@ class ForwardManyToOneDescriptor: try: rel_obj = self.field.get_cached_value(instance) except KeyError: - val = self.field.get_local_related_value(instance) - if None in val: - rel_obj = None + has_value = None not in self.field.get_local_related_value(instance) + ancestor_link = instance._meta.get_ancestor_link(self.field.model) if has_value else None + if ancestor_link and ancestor_link.is_cached(instance): + # An ancestor link will exist if this field is defined on a + # multi-table inheritance parent of the instance's class. + ancestor = ancestor_link.get_cached_value(instance) + # The value might be cached on an ancestor if the instance + # originated from walking down the inheritance chain. + rel_obj = self.field.get_cached_value(ancestor, default=None) else: + rel_obj = None + if rel_obj is None and has_value: rel_obj = self.get_object(instance) remote_field = self.field.remote_field # If this is a one-to-one relation, set the reverse accessor