Fixed #32442 -- Used converters on returning fields from INSERT statements.
This commit is contained in:
parent
619f26d289
commit
d9de74141e
|
@ -1405,6 +1405,7 @@ class SQLInsertCompiler(SQLCompiler):
|
|||
returning_fields and len(self.query.objs) != 1 and
|
||||
not self.connection.features.can_return_rows_from_bulk_insert
|
||||
)
|
||||
opts = self.query.get_meta()
|
||||
self.returning_fields = returning_fields
|
||||
with self.connection.cursor() as cursor:
|
||||
for sql, params in self.as_sql():
|
||||
|
@ -1412,13 +1413,21 @@ class SQLInsertCompiler(SQLCompiler):
|
|||
if not self.returning_fields:
|
||||
return []
|
||||
if self.connection.features.can_return_rows_from_bulk_insert and len(self.query.objs) > 1:
|
||||
return self.connection.ops.fetch_returned_insert_rows(cursor)
|
||||
if self.connection.features.can_return_columns_from_insert:
|
||||
rows = self.connection.ops.fetch_returned_insert_rows(cursor)
|
||||
elif self.connection.features.can_return_columns_from_insert:
|
||||
assert len(self.query.objs) == 1
|
||||
return [self.connection.ops.fetch_returned_insert_columns(cursor, self.returning_params)]
|
||||
return [(self.connection.ops.last_insert_id(
|
||||
cursor, self.query.get_meta().db_table, self.query.get_meta().pk.column
|
||||
rows = [self.connection.ops.fetch_returned_insert_columns(
|
||||
cursor, self.returning_params,
|
||||
)]
|
||||
else:
|
||||
rows = [(self.connection.ops.last_insert_id(
|
||||
cursor, opts.db_table, opts.pk.column,
|
||||
),)]
|
||||
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))
|
||||
return rows
|
||||
|
||||
|
||||
class SQLDeleteCompiler(SQLCompiler):
|
||||
|
|
|
@ -20,7 +20,7 @@ class MyWrapper:
|
|||
return self.value == other
|
||||
|
||||
|
||||
class MyAutoField(models.CharField):
|
||||
class MyWrapperField(models.CharField):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs['max_length'] = 10
|
||||
|
@ -58,3 +58,15 @@ class MyAutoField(models.CharField):
|
|||
if isinstance(value, MyWrapper):
|
||||
return str(value)
|
||||
return value
|
||||
|
||||
|
||||
class MyAutoField(models.BigAutoField):
|
||||
def from_db_value(self, value, expression, connection):
|
||||
if value is None:
|
||||
return None
|
||||
return MyWrapper(value)
|
||||
|
||||
def get_prep_value(self, value):
|
||||
if value is None:
|
||||
return None
|
||||
return int(value)
|
||||
|
|
|
@ -7,7 +7,7 @@ this behavior by explicitly adding ``primary_key=True`` to a field.
|
|||
|
||||
from django.db import models
|
||||
|
||||
from .fields import MyAutoField
|
||||
from .fields import MyAutoField, MyWrapperField
|
||||
|
||||
|
||||
class Employee(models.Model):
|
||||
|
@ -31,8 +31,12 @@ class Business(models.Model):
|
|||
|
||||
|
||||
class Bar(models.Model):
|
||||
id = MyAutoField(primary_key=True, db_index=True)
|
||||
id = MyWrapperField(primary_key=True, db_index=True)
|
||||
|
||||
|
||||
class Foo(models.Model):
|
||||
bar = models.ForeignKey(Bar, models.CASCADE)
|
||||
|
||||
|
||||
class CustomAutoFieldModel(models.Model):
|
||||
id = MyAutoField(primary_key=True)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from django.db import IntegrityError, transaction
|
||||
from django.test import TestCase, skipIfDBFeature
|
||||
from django.test import TestCase, skipIfDBFeature, skipUnlessDBFeature
|
||||
|
||||
from .models import Bar, Business, Employee, Foo
|
||||
from .fields import MyWrapper
|
||||
from .models import Bar, Business, CustomAutoFieldModel, Employee, Foo
|
||||
|
||||
|
||||
class BasicCustomPKTests(TestCase):
|
||||
|
@ -230,3 +231,13 @@ class CustomPKTests(TestCase):
|
|||
with self.assertRaises(IntegrityError):
|
||||
with transaction.atomic():
|
||||
Employee.objects.create(first_name="Tom", last_name="Smith")
|
||||
|
||||
def test_auto_field_subclass_create(self):
|
||||
obj = CustomAutoFieldModel.objects.create()
|
||||
self.assertIsInstance(obj.id, MyWrapper)
|
||||
|
||||
@skipUnlessDBFeature('can_return_rows_from_bulk_insert')
|
||||
def test_auto_field_subclass_bulk_create(self):
|
||||
obj = CustomAutoFieldModel()
|
||||
CustomAutoFieldModel.objects.bulk_create([obj])
|
||||
self.assertIsInstance(obj.id, MyWrapper)
|
||||
|
|
Loading…
Reference in New Issue