Fixed #29625 -- Made Model.refresh_from_db() clear prefetch related caches.
This commit is contained in:
parent
d311124be5
commit
cfb4845f06
|
@ -582,7 +582,14 @@ class Model(metaclass=ModelBase):
|
||||||
When accessing deferred fields of an instance, the deferred loading
|
When accessing deferred fields of an instance, the deferred loading
|
||||||
of the field will call this method.
|
of the field will call this method.
|
||||||
"""
|
"""
|
||||||
if fields is not None:
|
if fields is None:
|
||||||
|
self._prefetched_objects_cache = {}
|
||||||
|
else:
|
||||||
|
prefetched_objects_cache = getattr(self, '_prefetched_objects_cache', ())
|
||||||
|
for field in fields:
|
||||||
|
if field in prefetched_objects_cache:
|
||||||
|
del prefetched_objects_cache[field]
|
||||||
|
fields.remove(field)
|
||||||
if not fields:
|
if not fields:
|
||||||
return
|
return
|
||||||
if any(LOOKUP_SEP in f for f in fields):
|
if any(LOOKUP_SEP in f for f in fields):
|
||||||
|
|
|
@ -735,3 +735,27 @@ class ModelRefreshTests(TestCase):
|
||||||
article.save()
|
article.save()
|
||||||
featured.refresh_from_db()
|
featured.refresh_from_db()
|
||||||
self.assertEqual(featured.article.headline, 'Parrot programs in Python 2.0')
|
self.assertEqual(featured.article.headline, 'Parrot programs in Python 2.0')
|
||||||
|
|
||||||
|
def test_prefetched_cache_cleared(self):
|
||||||
|
a = Article.objects.create(pub_date=datetime(2005, 7, 28))
|
||||||
|
s = SelfRef.objects.create(article=a)
|
||||||
|
# refresh_from_db() without fields=[...]
|
||||||
|
a1_prefetched = Article.objects.prefetch_related('selfref_set').first()
|
||||||
|
self.assertCountEqual(a1_prefetched.selfref_set.all(), [s])
|
||||||
|
s.article = None
|
||||||
|
s.save()
|
||||||
|
# Relation is cleared and prefetch cache is stale.
|
||||||
|
self.assertCountEqual(a1_prefetched.selfref_set.all(), [s])
|
||||||
|
a1_prefetched.refresh_from_db()
|
||||||
|
# Cache was cleared and new results are available.
|
||||||
|
self.assertCountEqual(a1_prefetched.selfref_set.all(), [])
|
||||||
|
# refresh_from_db() with fields=[...]
|
||||||
|
a2_prefetched = Article.objects.prefetch_related('selfref_set').first()
|
||||||
|
self.assertCountEqual(a2_prefetched.selfref_set.all(), [])
|
||||||
|
s.article = a
|
||||||
|
s.save()
|
||||||
|
# Relation is added and prefetch cache is stale.
|
||||||
|
self.assertCountEqual(a2_prefetched.selfref_set.all(), [])
|
||||||
|
a2_prefetched.refresh_from_db(fields=['selfref_set'])
|
||||||
|
# Cache was cleared and new results are available.
|
||||||
|
self.assertCountEqual(a2_prefetched.selfref_set.all(), [s])
|
||||||
|
|
Loading…
Reference in New Issue