mirror of
https://github.com/django/django.git
synced 2025-10-25 22:56:12 +00:00
Refs #27222 -- Restored Model.save()'s refreshing of db_returning fields even if a value is set.
The logic could likely be adjusted to assign the pre_save value in most cases
to avoid the database transit but it could break in subtle ways so it's not
worth the complexity it would require.
Regression in 94680437a4.
Co-authored-by: Tim Graham <timograham@gmail.com>
This commit is contained in:
committed by
Jacob Walls
parent
1e7728888d
commit
4fcc2883fa
@@ -1142,23 +1142,30 @@ class Model(AltersData, metaclass=ModelBase):
|
|||||||
),
|
),
|
||||||
)["_order__max"]
|
)["_order__max"]
|
||||||
)
|
)
|
||||||
fields = [
|
insert_fields = [
|
||||||
f
|
f
|
||||||
for f in meta.local_concrete_fields
|
for f in meta.local_concrete_fields
|
||||||
if not f.generated and (pk_set or f is not meta.auto_field)
|
if not f.generated and (pk_set or f is not meta.auto_field)
|
||||||
]
|
]
|
||||||
returning_fields = list(meta.db_returning_fields)
|
returning_fields = list(meta.db_returning_fields)
|
||||||
for field in fields:
|
can_return_columns_from_insert = connections[
|
||||||
|
using
|
||||||
|
].features.can_return_columns_from_insert
|
||||||
|
for field in insert_fields:
|
||||||
value = (
|
value = (
|
||||||
getattr(self, field.attname) if raw else field.pre_save(self, False)
|
getattr(self, field.attname) if raw else field.pre_save(self, False)
|
||||||
)
|
)
|
||||||
if hasattr(value, "resolve_expression"):
|
if hasattr(value, "resolve_expression"):
|
||||||
if field not in returning_fields:
|
if field not in returning_fields:
|
||||||
returning_fields.append(field)
|
returning_fields.append(field)
|
||||||
elif field.db_returning:
|
elif (
|
||||||
|
field.db_returning
|
||||||
|
and not can_return_columns_from_insert
|
||||||
|
and not (pk_set and field is meta.auto_field)
|
||||||
|
):
|
||||||
returning_fields.remove(field)
|
returning_fields.remove(field)
|
||||||
results = self._do_insert(
|
results = self._do_insert(
|
||||||
cls._base_manager, using, fields, returning_fields, raw
|
cls._base_manager, using, insert_fields, returning_fields, raw
|
||||||
)
|
)
|
||||||
if results:
|
if results:
|
||||||
self._assign_returned_values(results[0], returning_fields)
|
self._assign_returned_values(results[0], returning_fields)
|
||||||
|
|||||||
@@ -215,6 +215,14 @@ class ModelInstanceCreationTests(TestCase):
|
|||||||
with self.assertNumQueries(1):
|
with self.assertNumQueries(1):
|
||||||
PrimaryKeyWithFalseyDbDefault().save()
|
PrimaryKeyWithFalseyDbDefault().save()
|
||||||
|
|
||||||
|
def test_auto_field_with_value_refreshed(self):
|
||||||
|
"""
|
||||||
|
An auto field must be refreshed by Model.save() even when a value is
|
||||||
|
set because the database may return a value of a different type.
|
||||||
|
"""
|
||||||
|
a = Article.objects.create(pk="123456", pub_date=datetime(2025, 9, 16))
|
||||||
|
self.assertEqual(a.pk, 123456)
|
||||||
|
|
||||||
|
|
||||||
class ModelTest(TestCase):
|
class ModelTest(TestCase):
|
||||||
def test_objects_attribute_is_only_available_on_the_class_itself(self):
|
def test_objects_attribute_is_only_available_on_the_class_itself(self):
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ class ReturningValuesTests(TestCase):
|
|||||||
self.assertTrue(obj.created)
|
self.assertTrue(obj.created)
|
||||||
self.assertIsInstance(obj.created, datetime.datetime)
|
self.assertIsInstance(obj.created, datetime.datetime)
|
||||||
|
|
||||||
|
def test_insert_returning_non_integer_from_literal_value(self):
|
||||||
|
obj = NonIntegerPKReturningModel.objects.create(pk="2025-01-01")
|
||||||
|
self.assertTrue(obj.created)
|
||||||
|
self.assertIsInstance(obj.created, datetime.datetime)
|
||||||
|
|
||||||
def test_insert_returning_multiple(self):
|
def test_insert_returning_multiple(self):
|
||||||
with CaptureQueriesContext(connection) as captured_queries:
|
with CaptureQueriesContext(connection) as captured_queries:
|
||||||
obj = ReturningModel.objects.create()
|
obj = ReturningModel.objects.create()
|
||||||
|
|||||||
Reference in New Issue
Block a user