Fixed #29076 -- Made Model.refresh_from_db() clear cached relationships even if the related id doesn't change.

This commit is contained in:
Jon Dufresne 2018-01-30 07:43:53 -08:00 committed by Tim Graham
parent 46b3e3ffdc
commit 136bf5c214
3 changed files with 15 additions and 12 deletions

View File

@ -609,13 +609,9 @@ class Model(metaclass=ModelBase):
# This field wasn't refreshed - skip ahead.
continue
setattr(self, field.attname, getattr(db_instance, field.attname))
# Throw away stale foreign key references.
# Clear cached foreign keys.
if field.is_relation and field.is_cached(self):
rel_instance = field.get_cached_value(self)
local_val = getattr(db_instance, field.attname)
related_val = None if rel_instance is None else getattr(rel_instance, field.target_field.attname)
if local_val != related_val or (local_val is None and related_val is None):
field.delete_cached_value(self)
field.delete_cached_value(self)
# Clear cached relations.
for field in self._meta.related_objects:

View File

@ -137,12 +137,7 @@ following is done:
1. All non-deferred fields of the model are updated to the values currently
present in the database.
2. The previously loaded related instances for which the relation's value is no
longer valid are removed from the reloaded instance. For example, if you have
a foreign key from the reloaded instance to another model with name
``Author``, then if ``obj.author_id != obj.author.id``, ``obj.author`` will
be thrown away, and when next accessed it will be reloaded with the value of
``obj.author_id``.
2. Any cached relations are cleared from the reloaded instance.
Only fields of the model are reloaded from the database. Other
database-dependent values such as annotations aren't reloaded. Any

View File

@ -722,3 +722,15 @@ class ModelRefreshTests(TestCase):
FeaturedArticle.objects.create(article_id=article.pk)
article.refresh_from_db()
self.assertTrue(hasattr(article, 'featured'))
def test_refresh_clears_one_to_one_field(self):
article = Article.objects.create(
headline='Parrot programs in Python',
pub_date=datetime(2005, 7, 28),
)
featured = FeaturedArticle.objects.create(article_id=article.pk)
self.assertEqual(featured.article.headline, 'Parrot programs in Python')
article.headline = 'Parrot programs in Python 2.0'
article.save()
featured.refresh_from_db()
self.assertEqual(featured.article.headline, 'Parrot programs in Python 2.0')