mirror of
https://github.com/django/django.git
synced 2024-12-22 09:05:43 +00:00
Fixed #35950 -- Restored refreshing of relations when fields deferred.
Thank you to Simon Charette and Sarah Boyce for the review.
Regression in 73df8b54a2
.
This commit is contained in:
parent
32b9e00b0c
commit
2f6b096b83
@ -726,12 +726,13 @@ class Model(AltersData, metaclass=ModelBase):
|
||||
if fields is not None:
|
||||
db_instance_qs = db_instance_qs.only(*fields)
|
||||
elif deferred_fields:
|
||||
fields = {
|
||||
f.attname
|
||||
for f in self._meta.concrete_fields
|
||||
if f.attname not in deferred_fields
|
||||
}
|
||||
db_instance_qs = db_instance_qs.only(*fields)
|
||||
db_instance_qs = db_instance_qs.only(
|
||||
*{
|
||||
f.attname
|
||||
for f in self._meta.concrete_fields
|
||||
if f.attname not in deferred_fields
|
||||
}
|
||||
)
|
||||
|
||||
db_instance = db_instance_qs.get()
|
||||
non_loaded_fields = db_instance.get_deferred_fields()
|
||||
@ -748,9 +749,9 @@ class Model(AltersData, metaclass=ModelBase):
|
||||
field.delete_cached_value(self)
|
||||
|
||||
# Clear cached relations.
|
||||
for field in self._meta.related_objects:
|
||||
if (fields is None or field.name in fields) and field.is_cached(self):
|
||||
field.delete_cached_value(self)
|
||||
for rel in self._meta.related_objects:
|
||||
if (fields is None or rel.name in fields) and rel.is_cached(self):
|
||||
rel.delete_cached_value(self)
|
||||
|
||||
# Clear cached private relations.
|
||||
for field in self._meta.private_fields:
|
||||
|
@ -12,3 +12,7 @@ Bugfixes
|
||||
|
||||
* Fixed a crash in ``createsuperuser`` on Python 3.13+ caused by an unhandled
|
||||
``OSError`` when the username could not be determined (:ticket:`35942`).
|
||||
|
||||
* Fixed a regression in Django 5.1 where relational fields were not updated
|
||||
when calling ``Model.refresh_from_db()`` on instances with deferred fields
|
||||
(:ticket:`35950`).
|
||||
|
@ -57,6 +57,15 @@ class GenericForeignKeyTests(TestCase):
|
||||
self.assertIsNot(answer.question, old_question_obj)
|
||||
self.assertEqual(answer.question, old_question_obj)
|
||||
|
||||
def test_clear_cached_generic_relation_when_deferred(self):
|
||||
question = Question.objects.create(text="question")
|
||||
Answer.objects.create(text="answer", question=question)
|
||||
answer = Answer.objects.defer("text").get()
|
||||
old_question_obj = answer.question
|
||||
# The reverse relation is refreshed even when the text field is deferred.
|
||||
answer.refresh_from_db()
|
||||
self.assertIsNot(answer.question, old_question_obj)
|
||||
|
||||
|
||||
class GenericRelationTests(TestCase):
|
||||
def test_value_to_string(self):
|
||||
|
@ -290,6 +290,14 @@ class TestDefer2(AssertionMixin, TestCase):
|
||||
self.assertEqual(rf2.name, "new foo")
|
||||
self.assertEqual(rf2.value, "new bar")
|
||||
|
||||
def test_refresh_when_one_field_deferred(self):
|
||||
s = Secondary.objects.create()
|
||||
PrimaryOneToOne.objects.create(name="foo", value="bar", related=s)
|
||||
s = Secondary.objects.defer("first").get()
|
||||
p_before = s.primary_o2o
|
||||
s.refresh_from_db()
|
||||
self.assertIsNot(s.primary_o2o, p_before)
|
||||
|
||||
|
||||
class InvalidDeferTests(SimpleTestCase):
|
||||
def test_invalid_defer(self):
|
||||
|
Loading…
Reference in New Issue
Block a user