Kaydet (Commit) cfb4845f authored tarafından Ming Qin's avatar Ming Qin Kaydeden (comit) Tim Graham

Fixed #29625 -- Made Model.refresh_from_db() clear prefetch related caches.

üst d311124b
...@@ -582,7 +582,14 @@ class Model(metaclass=ModelBase): ...@@ -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): ...@@ -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])
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment