mirror of
				https://github.com/django/django.git
				synced 2025-10-31 01:25:32 +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:
		| @@ -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: | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user