[2.0.x] Fixed #27846 -- Made Model.refresh_from_db() clear cached relations.

Backport of a7b5ad8b19 from master
This commit is contained in:
Paulo 2017-09-19 12:51:19 -05:00 committed by Tim Graham
parent 51998a2988
commit 5d3f2aa3f1
3 changed files with 22 additions and 1 deletions

View File

@ -627,6 +627,12 @@ class Model(metaclass=ModelBase):
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)
# Clear cached relations.
for field in self._meta.related_objects:
if field.is_cached(self):
field.delete_cached_value(self)
self._state.db = db_instance._state.db
def serializable_value(self, field_name):

View File

@ -17,6 +17,10 @@ class Article(models.Model):
return self.headline
class FeaturedArticle(models.Model):
article = models.OneToOneField(Article, models.CASCADE, related_name='featured')
class ArticleSelectOnSave(Article):
class Meta:
proxy = True

View File

@ -11,7 +11,7 @@ from django.test import (
)
from django.utils.translation import gettext_lazy
from .models import Article, ArticleSelectOnSave, SelfRef
from .models import Article, ArticleSelectOnSave, FeaturedArticle, SelfRef
class ModelInstanceCreationTests(TestCase):
@ -745,3 +745,14 @@ class ModelRefreshTests(TestCase):
a = Article.objects.create(pub_date=self._truncate_ms(datetime.now()))
with self.assertNumQueries(0):
a.refresh_from_db(fields=[])
def test_refresh_clears_reverse_related(self):
"""refresh_from_db() clear cached reverse relations."""
article = Article.objects.create(
headline='Parrot programs in Python',
pub_date=datetime(2005, 7, 28),
)
self.assertFalse(hasattr(article, 'featured'))
FeaturedArticle.objects.create(article_id=article.pk)
article.refresh_from_db()
self.assertTrue(hasattr(article, 'featured'))