mirror of
https://github.com/django/django.git
synced 2025-06-05 03:29:12 +00:00
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
|
# name) to the data type to use for the Cast() function, if different from
|
||||||
# DatabaseWrapper.data_types.
|
# DatabaseWrapper.data_types.
|
||||||
cast_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):
|
def __init__(self, connection):
|
||||||
self.connection = connection
|
self.connection = connection
|
||||||
|
@ -24,6 +24,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
|||||||
'PositiveIntegerField': 'unsigned integer',
|
'PositiveIntegerField': 'unsigned integer',
|
||||||
'PositiveSmallIntegerField': 'unsigned integer',
|
'PositiveSmallIntegerField': 'unsigned integer',
|
||||||
}
|
}
|
||||||
|
cast_char_field_without_max_length = 'char'
|
||||||
|
|
||||||
def date_extract_sql(self, lookup_type, field_name):
|
def date_extract_sql(self, lookup_type, field_name):
|
||||||
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
||||||
|
@ -49,6 +49,9 @@ BEGIN
|
|||||||
END;
|
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):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.set_operators['difference'] = 'MINUS'
|
self.set_operators['difference'] = 'MINUS'
|
||||||
|
@ -5,6 +5,8 @@ from django.db.backends.base.operations import BaseDatabaseOperations
|
|||||||
|
|
||||||
|
|
||||||
class DatabaseOperations(BaseDatabaseOperations):
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
cast_char_field_without_max_length = 'varchar'
|
||||||
|
|
||||||
def unification_cast_sql(self, output_field):
|
def unification_cast_sql(self, output_field):
|
||||||
internal_type = output_field.get_internal_type()
|
internal_type = output_field.get_internal_type()
|
||||||
if internal_type in ("GenericIPAddressField", "IPAddressField", "TimeField", "UUIDField"):
|
if internal_type in ("GenericIPAddressField", "IPAddressField", "TimeField", "UUIDField"):
|
||||||
|
@ -14,6 +14,8 @@ from django.utils.duration import duration_string
|
|||||||
|
|
||||||
|
|
||||||
class DatabaseOperations(BaseDatabaseOperations):
|
class DatabaseOperations(BaseDatabaseOperations):
|
||||||
|
cast_char_field_without_max_length = 'text'
|
||||||
|
|
||||||
def bulk_batch_size(self, fields, objs):
|
def bulk_batch_size(self, fields, objs):
|
||||||
"""
|
"""
|
||||||
SQLite has a compile-time default (SQLITE_LIMIT_VARIABLE_NUMBER) of
|
SQLite has a compile-time default (SQLITE_LIMIT_VARIABLE_NUMBER) of
|
||||||
|
@ -1066,6 +1066,11 @@ class CharField(Field):
|
|||||||
else:
|
else:
|
||||||
return []
|
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):
|
def get_internal_type(self):
|
||||||
return "CharField"
|
return "CharField"
|
||||||
|
|
||||||
|
@ -348,6 +348,12 @@ backends.
|
|||||||
requires that the arguments to ``OF`` be columns rather than tables, set
|
requires that the arguments to ``OF`` be columns rather than tables, set
|
||||||
``DatabaseFeatures.select_for_update_of_column = True``.
|
``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
|
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)),)
|
numbers = Author.objects.annotate(cast_string=Cast('age', models.CharField(max_length=255)),)
|
||||||
self.assertEqual(numbers.get().cast_string, '1')
|
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'".
|
# Silence "Truncated incorrect CHAR(1) value: 'Bob'".
|
||||||
@ignore_warnings(module='django.db.backends.mysql.base')
|
@ignore_warnings(module='django.db.backends.mysql.base')
|
||||||
@skipUnlessDBFeature('supports_cast_with_precision')
|
@skipUnlessDBFeature('supports_cast_with_precision')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user