Fixed #28371 -- Fixed Cast() with CharField if the max_length argument isn't provided.
Thanks Tim Graham for the review.
This commit is contained in:
parent
14172cf442
commit
b61d5b1991
|
@ -36,6 +36,8 @@ class BaseDatabaseOperations:
|
|||
# name) to the data type to use for the Cast() function, if different from
|
||||
# DatabaseWrapper.data_types.
|
||||
cast_data_types = {}
|
||||
# CharField data type if the max_length argument isn't provided.
|
||||
cast_char_field_without_max_length = None
|
||||
|
||||
def __init__(self, connection):
|
||||
self.connection = connection
|
||||
|
|
|
@ -24,6 +24,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||
'PositiveIntegerField': 'unsigned integer',
|
||||
'PositiveSmallIntegerField': 'unsigned integer',
|
||||
}
|
||||
cast_char_field_without_max_length = 'char'
|
||||
|
||||
def date_extract_sql(self, lookup_type, field_name):
|
||||
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
||||
|
|
|
@ -49,6 +49,9 @@ BEGIN
|
|||
END;
|
||||
/"""
|
||||
|
||||
# Oracle doesn't support string without precision; use the max string size.
|
||||
cast_char_field_without_max_length = 'NVARCHAR2(2000)'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.set_operators['difference'] = 'MINUS'
|
||||
|
|
|
@ -5,6 +5,8 @@ from django.db.backends.base.operations import BaseDatabaseOperations
|
|||
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
cast_char_field_without_max_length = 'varchar'
|
||||
|
||||
def unification_cast_sql(self, output_field):
|
||||
internal_type = output_field.get_internal_type()
|
||||
if internal_type in ("GenericIPAddressField", "IPAddressField", "TimeField", "UUIDField"):
|
||||
|
|
|
@ -14,6 +14,8 @@ from django.utils.duration import duration_string
|
|||
|
||||
|
||||
class DatabaseOperations(BaseDatabaseOperations):
|
||||
cast_char_field_without_max_length = 'text'
|
||||
|
||||
def bulk_batch_size(self, fields, objs):
|
||||
"""
|
||||
SQLite has a compile-time default (SQLITE_LIMIT_VARIABLE_NUMBER) of
|
||||
|
|
|
@ -1066,6 +1066,11 @@ class CharField(Field):
|
|||
else:
|
||||
return []
|
||||
|
||||
def cast_db_type(self, connection):
|
||||
if self.max_length is None:
|
||||
return connection.ops.cast_char_field_without_max_length
|
||||
return super().cast_db_type(connection)
|
||||
|
||||
def get_internal_type(self):
|
||||
return "CharField"
|
||||
|
||||
|
|
|
@ -348,6 +348,12 @@ backends.
|
|||
requires that the arguments to ``OF`` be columns rather than tables, set
|
||||
``DatabaseFeatures.select_for_update_of_column = True``.
|
||||
|
||||
* Third-party database backends should add a
|
||||
``DatabaseOperations.cast_char_field_without_max_length`` attribute with the
|
||||
database data type that will be used in the
|
||||
:class:`~django.db.models.functions.Cast` function for a ``CharField`` if the
|
||||
``max_length`` argument isn't provided.
|
||||
|
||||
Dropped support for Oracle 11.2
|
||||
-------------------------------
|
||||
|
||||
|
|
|
@ -19,6 +19,10 @@ class CastTests(TestCase):
|
|||
numbers = Author.objects.annotate(cast_string=Cast('age', models.CharField(max_length=255)),)
|
||||
self.assertEqual(numbers.get().cast_string, '1')
|
||||
|
||||
def test_cast_to_char_field_without_max_length(self):
|
||||
numbers = Author.objects.annotate(cast_string=Cast('age', models.CharField()))
|
||||
self.assertEqual(numbers.get().cast_string, '1')
|
||||
|
||||
# Silence "Truncated incorrect CHAR(1) value: 'Bob'".
|
||||
@ignore_warnings(module='django.db.backends.mysql.base')
|
||||
@skipUnlessDBFeature('supports_cast_with_precision')
|
||||
|
|
Loading…
Reference in New Issue