mirror of
https://github.com/django/django.git
synced 2025-02-01 21:29:24 +00:00
Fixed #35024 -- Fixed model instance creation crash on GeneratedField.output_field with backend converters.
Regression in d9de74141e8a920940f1b91ed0a3ccb835b55729. This is a long standing issue, however it caused a crash of GeneratedFields for all output fields that have backend-specific converters when the RETURNING clause is not supported (MySQL and SQLite < 3.35). That's why severity was exacerbated.
This commit is contained in:
parent
2dca98f4f7
commit
5b3b791e90
@ -1819,6 +1819,7 @@ class SQLInsertCompiler(SQLCompiler):
|
||||
)
|
||||
opts = self.query.get_meta()
|
||||
self.returning_fields = returning_fields
|
||||
cols = []
|
||||
with self.connection.cursor() as cursor:
|
||||
for sql, params in self.as_sql():
|
||||
cursor.execute(sql, params)
|
||||
@ -1829,6 +1830,7 @@ class SQLInsertCompiler(SQLCompiler):
|
||||
and len(self.query.objs) > 1
|
||||
):
|
||||
rows = self.connection.ops.fetch_returned_insert_rows(cursor)
|
||||
cols = [field.get_col(opts.db_table) for field in self.returning_fields]
|
||||
elif self.connection.features.can_return_columns_from_insert:
|
||||
assert len(self.query.objs) == 1
|
||||
rows = [
|
||||
@ -1837,7 +1839,9 @@ class SQLInsertCompiler(SQLCompiler):
|
||||
self.returning_params,
|
||||
)
|
||||
]
|
||||
cols = [field.get_col(opts.db_table) for field in self.returning_fields]
|
||||
else:
|
||||
cols = [opts.pk.get_col(opts.db_table)]
|
||||
rows = [
|
||||
(
|
||||
self.connection.ops.last_insert_id(
|
||||
@ -1847,7 +1851,6 @@ class SQLInsertCompiler(SQLCompiler):
|
||||
),
|
||||
)
|
||||
]
|
||||
cols = [field.get_col(opts.db_table) for field in self.returning_fields]
|
||||
converters = self.get_converters(cols)
|
||||
if converters:
|
||||
rows = list(self.apply_converters(rows, converters))
|
||||
|
@ -12,3 +12,7 @@ Bugfixes
|
||||
* Reallowed, following a regression in Django 5.0, using a foreign key to a
|
||||
model with a primary key that is not ``AutoField`` in
|
||||
:attr:`.ModelAdmin.list_filter` (:ticket:`35020`).
|
||||
|
||||
* Fixed a long standing bug in handling the ``RETURNING INTO`` clause that
|
||||
caused a crash when creating a model instance with a ``GeneratedField`` which
|
||||
``output_field`` had backend-specific converters (:ticket:`35024`).
|
||||
|
@ -482,6 +482,18 @@ class UUIDGrandchild(UUIDChild):
|
||||
pass
|
||||
|
||||
|
||||
class GeneratedModelFieldWithConverters(models.Model):
|
||||
field = models.UUIDField()
|
||||
field_copy = models.GeneratedField(
|
||||
expression=F("field"),
|
||||
output_field=models.UUIDField(),
|
||||
db_persist=True,
|
||||
)
|
||||
|
||||
class Meta:
|
||||
required_db_features = {"supports_stored_generated_columns"}
|
||||
|
||||
|
||||
class GeneratedModel(models.Model):
|
||||
a = models.IntegerField()
|
||||
b = models.IntegerField()
|
||||
|
@ -1,3 +1,5 @@
|
||||
import uuid
|
||||
|
||||
from django.apps import apps
|
||||
from django.db import IntegrityError, connection
|
||||
from django.db.models import (
|
||||
@ -14,6 +16,7 @@ from django.test.utils import isolate_apps
|
||||
|
||||
from .models import (
|
||||
GeneratedModel,
|
||||
GeneratedModelFieldWithConverters,
|
||||
GeneratedModelNull,
|
||||
GeneratedModelNullVirtual,
|
||||
GeneratedModelOutputFieldDbCollation,
|
||||
@ -266,6 +269,11 @@ class StoredGeneratedFieldTests(GeneratedFieldTestMixin, TestCase):
|
||||
output_field_db_collation_model = GeneratedModelOutputFieldDbCollation
|
||||
params_model = GeneratedModelParams
|
||||
|
||||
def test_create_field_with_db_converters(self):
|
||||
obj = GeneratedModelFieldWithConverters.objects.create(field=uuid.uuid4())
|
||||
obj = self._refresh_if_needed(obj)
|
||||
self.assertEqual(obj.field, obj.field_copy)
|
||||
|
||||
|
||||
@skipUnlessDBFeature("supports_virtual_generated_columns")
|
||||
class VirtualGeneratedFieldTests(GeneratedFieldTestMixin, TestCase):
|
||||
|
Loading…
x
Reference in New Issue
Block a user