summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaulo <commonzenpython@gmail.com>2018-05-14 11:01:53 -0400
committerTim Graham <timograham@gmail.com>2018-05-14 21:17:02 -0400
commit265506bbc347a6b3fcc6c66ab1a2417b3b7ea57a (patch)
tree3e3f87aed1f116a0bb9b8ce7aeb6bdd7d7272e38
parentcae010728763e0e716b87f4ccd8b3fa54eb20602 (diff)
downloaddjango-265506bbc347a6b3fcc6c66ab1a2417b3b7ea57a.tar.gz
Refs #28834 -- Moved ancestor field cached value fallback to related fields descriptor.
-rw-r--r--django/db/models/fields/mixins.py16
-rw-r--r--django/db/models/fields/related_descriptors.py14
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