mirror of
https://github.com/django/django.git
synced 2025-06-03 18:49:12 +00:00
[5.1.x] Fixed #35950 -- Restored refreshing of relations when fields deferred.
Thank you to Simon Charette and Sarah Boyce for the review. Regression in 73df8b54a2fab53bec4c7573cda5ad8c869c2fd8. Backport of 2f6b096b83c55317c7ceef2d8d5dc3bee33293dc from main.
This commit is contained in:
parent
ee2698dcca
commit
6e3e7353e0
@ -717,12 +717,13 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
if fields is not None:
|
if fields is not None:
|
||||||
db_instance_qs = db_instance_qs.only(*fields)
|
db_instance_qs = db_instance_qs.only(*fields)
|
||||||
elif deferred_fields:
|
elif deferred_fields:
|
||||||
fields = {
|
db_instance_qs = db_instance_qs.only(
|
||||||
f.attname
|
*{
|
||||||
for f in self._meta.concrete_fields
|
f.attname
|
||||||
if f.attname not in deferred_fields
|
for f in self._meta.concrete_fields
|
||||||
}
|
if f.attname not in deferred_fields
|
||||||
db_instance_qs = db_instance_qs.only(*fields)
|
}
|
||||||
|
)
|
||||||
|
|
||||||
db_instance = db_instance_qs.get()
|
db_instance = db_instance_qs.get()
|
||||||
non_loaded_fields = db_instance.get_deferred_fields()
|
non_loaded_fields = db_instance.get_deferred_fields()
|
||||||
@ -739,9 +740,9 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
field.delete_cached_value(self)
|
field.delete_cached_value(self)
|
||||||
|
|
||||||
# Clear cached relations.
|
# Clear cached relations.
|
||||||
for field in self._meta.related_objects:
|
for rel in self._meta.related_objects:
|
||||||
if (fields is None or field.name in fields) and field.is_cached(self):
|
if (fields is None or rel.name in fields) and rel.is_cached(self):
|
||||||
field.delete_cached_value(self)
|
rel.delete_cached_value(self)
|
||||||
|
|
||||||
# Clear cached private relations.
|
# Clear cached private relations.
|
||||||
for field in self._meta.private_fields:
|
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
|
* Fixed a crash in ``createsuperuser`` on Python 3.13+ caused by an unhandled
|
||||||
``OSError`` when the username could not be determined (:ticket:`35942`).
|
``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.assertIsNot(answer.question, old_question_obj)
|
||||||
self.assertEqual(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):
|
class GenericRelationTests(TestCase):
|
||||||
def test_value_to_string(self):
|
def test_value_to_string(self):
|
||||||
|
@ -290,6 +290,14 @@ class TestDefer2(AssertionMixin, TestCase):
|
|||||||
self.assertEqual(rf2.name, "new foo")
|
self.assertEqual(rf2.name, "new foo")
|
||||||
self.assertEqual(rf2.value, "new bar")
|
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):
|
class InvalidDeferTests(SimpleTestCase):
|
||||||
def test_invalid_defer(self):
|
def test_invalid_defer(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user