1
0
mirror of https://github.com/django/django.git synced 2025-09-18 06:59: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 94680437a45a71c70ca8bd2e68b72aa1e2eff337.

Co-authored-by: Tim Graham <timograham@gmail.com>
This commit is contained in:
Simon Charette 2025-09-16 18:10:27 -04:00 committed by Jacob Walls
parent 1e7728888d
commit 4fcc2883fa
3 changed files with 24 additions and 4 deletions

View File

@ -1142,23 +1142,30 @@ class Model(AltersData, metaclass=ModelBase):
),
)["_order__max"]
)
fields = [
insert_fields = [
f
for f in meta.local_concrete_fields
if not f.generated and (pk_set or f is not meta.auto_field)
]
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 = (
getattr(self, field.attname) if raw else field.pre_save(self, False)
)
if hasattr(value, "resolve_expression"):
if field not in returning_fields:
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)
results = self._do_insert(
cls._base_manager, using, fields, returning_fields, raw
cls._base_manager, using, insert_fields, returning_fields, raw
)
if results:
self._assign_returned_values(results[0], returning_fields)

View File

@ -215,6 +215,14 @@ class ModelInstanceCreationTests(TestCase):
with self.assertNumQueries(1):
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):
def test_objects_attribute_is_only_available_on_the_class_itself(self):

View File

@ -26,6 +26,11 @@ class ReturningValuesTests(TestCase):
self.assertTrue(obj.created)
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):
with CaptureQueriesContext(connection) as captured_queries:
obj = ReturningModel.objects.create()