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:
parent
1e7728888d
commit
4fcc2883fa
@ -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)
|
||||
|
@ -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):
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user