Skip to content

Commit

Permalink
Fixed #35024 -- Fixed model instance creation crash on GeneratedField…
Browse files Browse the repository at this point in the history
….output_field with backend converters.

Regression in d9de741.

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.
  • Loading branch information
felixxm authored Dec 7, 2023
1 parent 2dca98f commit 5b3b791
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 1 deletion.
5 changes: 4 additions & 1 deletion django/db/models/sql/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -1819,6 +1819,7 @@ def execute_sql(self, returning_fields=None):
)
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)
Expand All @@ -1829,6 +1830,7 @@ def execute_sql(self, returning_fields=None):
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 = [
Expand All @@ -1837,7 +1839,9 @@ def execute_sql(self, returning_fields=None):
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(
Expand All @@ -1847,7 +1851,6 @@ def execute_sql(self, returning_fields=None):
),
)
]
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))
Expand Down
4 changes: 4 additions & 0 deletions docs/releases/5.0.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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`).
12 changes: 12 additions & 0 deletions tests/model_fields/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
8 changes: 8 additions & 0 deletions tests/model_fields/test_generatedfield.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import uuid

from django.apps import apps
from django.db import IntegrityError, connection
from django.db.models import (
Expand All @@ -14,6 +16,7 @@

from .models import (
GeneratedModel,
GeneratedModelFieldWithConverters,
GeneratedModelNull,
GeneratedModelNullVirtual,
GeneratedModelOutputFieldDbCollation,
Expand Down Expand Up @@ -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):
Expand Down

0 comments on commit 5b3b791

Please sign in to comment.