mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
Fixed #29076 -- Made Model.refresh_from_db() clear cached relationships even if the related id doesn't change.
This commit is contained in:
parent
46b3e3ffdc
commit
136bf5c214
@ -609,13 +609,9 @@ class Model(metaclass=ModelBase):
|
|||||||
# This field wasn't refreshed - skip ahead.
|
# This field wasn't refreshed - skip ahead.
|
||||||
continue
|
continue
|
||||||
setattr(self, field.attname, getattr(db_instance, field.attname))
|
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):
|
if field.is_relation and field.is_cached(self):
|
||||||
rel_instance = field.get_cached_value(self)
|
field.delete_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)
|
|
||||||
|
|
||||||
# Clear cached relations.
|
# Clear cached relations.
|
||||||
for field in self._meta.related_objects:
|
for field in self._meta.related_objects:
|
||||||
|
@ -137,12 +137,7 @@ following is done:
|
|||||||
|
|
||||||
1. All non-deferred fields of the model are updated to the values currently
|
1. All non-deferred fields of the model are updated to the values currently
|
||||||
present in the database.
|
present in the database.
|
||||||
2. The previously loaded related instances for which the relation's value is no
|
2. Any cached relations are cleared from the reloaded instance.
|
||||||
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``.
|
|
||||||
|
|
||||||
Only fields of the model are reloaded from the database. Other
|
Only fields of the model are reloaded from the database. Other
|
||||||
database-dependent values such as annotations aren't reloaded. Any
|
database-dependent values such as annotations aren't reloaded. Any
|
||||||
|
@ -722,3 +722,15 @@ class ModelRefreshTests(TestCase):
|
|||||||
FeaturedArticle.objects.create(article_id=article.pk)
|
FeaturedArticle.objects.create(article_id=article.pk)
|
||||||
article.refresh_from_db()
|
article.refresh_from_db()
|
||||||
self.assertTrue(hasattr(article, 'featured'))
|
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')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user