Fixed #28370 -- Deprecated the context arg of Field.from_db_value() and Expression.convert_value().
Unused since a0d166306f
.
This commit is contained in:
parent
8d5095d8a3
commit
487362fa8f
|
@ -95,7 +95,7 @@ class MySQLOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
# https://dev.mysql.com/doc/refman/en/spatial-function-argument-handling.html
|
# https://dev.mysql.com/doc/refman/en/spatial-function-argument-handling.html
|
||||||
# MySQL 5.7.5 adds support for the empty geometry collections, but they are represented with invalid WKT.
|
# MySQL 5.7.5 adds support for the empty geometry collections, but they are represented with invalid WKT.
|
||||||
def convert_invalid_empty_geometry_collection(self, value, expression, connection, context):
|
def convert_invalid_empty_geometry_collection(self, value, expression, connection):
|
||||||
if value == b'GEOMETRYCOLLECTION()':
|
if value == b'GEOMETRYCOLLECTION()':
|
||||||
return b'GEOMETRYCOLLECTION EMPTY'
|
return b'GEOMETRYCOLLECTION EMPTY'
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -43,7 +43,7 @@ class Extent(GeoAggregate):
|
||||||
def __init__(self, expression, **extra):
|
def __init__(self, expression, **extra):
|
||||||
super().__init__(expression, output_field=ExtentField(), **extra)
|
super().__init__(expression, output_field=ExtentField(), **extra)
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
return connection.ops.convert_extent(value)
|
return connection.ops.convert_extent(value)
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ class Extent3D(GeoAggregate):
|
||||||
def __init__(self, expression, **extra):
|
def __init__(self, expression, **extra):
|
||||||
super().__init__(expression, output_field=ExtentField(), **extra)
|
super().__init__(expression, output_field=ExtentField(), **extra)
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
return connection.ops.convert_extent3d(value)
|
return connection.ops.convert_extent3d(value)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -255,7 +255,7 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField):
|
||||||
kwargs['geography'] = self.geography
|
kwargs['geography'] = self.geography
|
||||||
return name, path, args, kwargs
|
return name, path, args, kwargs
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
if value:
|
if value:
|
||||||
value = Geometry(value)
|
value = Geometry(value)
|
||||||
srid = value.srid
|
srid = value.srid
|
||||||
|
@ -351,7 +351,7 @@ class RasterField(BaseSpatialField):
|
||||||
self._check_connection(connection)
|
self._check_connection(connection)
|
||||||
return super().db_type(connection)
|
return super().db_type(connection)
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
return connection.ops.parse_raster(value)
|
return connection.ops.parse_raster(value)
|
||||||
|
|
||||||
def contribute_to_class(self, cls, name, **kwargs):
|
def contribute_to_class(self, cls, name, **kwargs):
|
||||||
|
|
|
@ -23,7 +23,7 @@ class AreaField(models.FloatField):
|
||||||
return value
|
return value
|
||||||
return getattr(value, self.area_att)
|
return getattr(value, self.area_att)
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
# If the database returns a Decimal, convert it to a float as expected
|
# If the database returns a Decimal, convert it to a float as expected
|
||||||
# by the Python geometric objects.
|
# by the Python geometric objects.
|
||||||
if isinstance(value, Decimal):
|
if isinstance(value, Decimal):
|
||||||
|
@ -54,7 +54,7 @@ class DistanceField(models.FloatField):
|
||||||
raise ValueError('Distance measure is supplied, but units are unknown for result.')
|
raise ValueError('Distance measure is supplied, but units are unknown for result.')
|
||||||
return getattr(value, self.distance_att)
|
return getattr(value, self.distance_att)
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
if value is None or not self.distance_att:
|
if value is None or not self.distance_att:
|
||||||
return value
|
return value
|
||||||
return Distance(**{self.distance_att: value})
|
return Distance(**{self.distance_att: value})
|
||||||
|
|
|
@ -13,7 +13,7 @@ class ArrayAgg(Aggregate):
|
||||||
def __init__(self, expression, distinct=False, **extra):
|
def __init__(self, expression, distinct=False, **extra):
|
||||||
super().__init__(expression, distinct='DISTINCT ' if distinct else '', **extra)
|
super().__init__(expression, distinct='DISTINCT ' if distinct else '', **extra)
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if not value:
|
if not value:
|
||||||
return []
|
return []
|
||||||
return value
|
return value
|
||||||
|
@ -39,7 +39,7 @@ class JSONBAgg(Aggregate):
|
||||||
function = 'JSONB_AGG'
|
function = 'JSONB_AGG'
|
||||||
output_field = JSONField()
|
output_field = JSONField()
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if not value:
|
if not value:
|
||||||
return []
|
return []
|
||||||
return value
|
return value
|
||||||
|
@ -53,7 +53,7 @@ class StringAgg(Aggregate):
|
||||||
distinct = 'DISTINCT ' if distinct else ''
|
distinct = 'DISTINCT ' if distinct else ''
|
||||||
super().__init__(expression, delimiter=delimiter, distinct=distinct, **extra)
|
super().__init__(expression, delimiter=delimiter, distinct=distinct, **extra)
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if not value:
|
if not value:
|
||||||
return ''
|
return ''
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -41,7 +41,7 @@ class RegrCount(StatAggregate):
|
||||||
def __init__(self, y, x):
|
def __init__(self, y, x):
|
||||||
super().__init__(y=y, x=x, output_field=IntegerField())
|
super().__init__(y=y, x=x, output_field=IntegerField())
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return 0
|
return 0
|
||||||
return int(value)
|
return int(value)
|
||||||
|
|
|
@ -6,6 +6,7 @@ from django.contrib.postgres.validators import ArrayMaxLengthValidator
|
||||||
from django.core import checks, exceptions
|
from django.core import checks, exceptions
|
||||||
from django.db.models import Field, IntegerField, Transform
|
from django.db.models import Field, IntegerField, Transform
|
||||||
from django.db.models.lookups import Exact, In
|
from django.db.models.lookups import Exact, In
|
||||||
|
from django.utils.inspect import func_supports_parameter
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from ..utils import prefix_validation_error
|
from ..utils import prefix_validation_error
|
||||||
|
@ -103,11 +104,13 @@ class ArrayField(Field):
|
||||||
value = [self.base_field.to_python(val) for val in vals]
|
value = [self.base_field.to_python(val) for val in vals]
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def _from_db_value(self, value, expression, connection, context):
|
def _from_db_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
return [
|
return [
|
||||||
self.base_field.from_db_value(item, expression, connection, context)
|
self.base_field.from_db_value(item, expression, connection, {})
|
||||||
|
if func_supports_parameter(self.base_field.from_db_value, 'context') # RemovedInDjango30Warning
|
||||||
|
else self.base_field.from_db_value(item, expression, connection)
|
||||||
for item in value
|
for item in value
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ from django.core.cache.backends.base import DEFAULT_TIMEOUT, BaseCache
|
||||||
from django.db import DatabaseError, connections, models, router, transaction
|
from django.db import DatabaseError, connections, models, router, transaction
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.encoding import force_bytes
|
from django.utils.encoding import force_bytes
|
||||||
|
from django.utils.inspect import func_supports_parameter
|
||||||
|
|
||||||
|
|
||||||
class Options:
|
class Options:
|
||||||
|
@ -64,7 +65,10 @@ class DatabaseCache(BaseDatabaseCache):
|
||||||
expression = models.Expression(output_field=models.DateTimeField())
|
expression = models.Expression(output_field=models.DateTimeField())
|
||||||
for converter in (connection.ops.get_db_converters(expression) +
|
for converter in (connection.ops.get_db_converters(expression) +
|
||||||
expression.get_db_converters(connection)):
|
expression.get_db_converters(connection)):
|
||||||
expires = converter(expires, expression, connection, {})
|
if func_supports_parameter(converter, 'context'): # RemovedInDjango30Warning
|
||||||
|
expires = converter(expires, expression, connection, {})
|
||||||
|
else:
|
||||||
|
expires = converter(expires, expression, connection)
|
||||||
|
|
||||||
if expires < timezone.now():
|
if expires < timezone.now():
|
||||||
db = router.db_for_write(self.cache_model_class)
|
db = router.db_for_write(self.cache_model_class)
|
||||||
|
@ -126,7 +130,10 @@ class DatabaseCache(BaseDatabaseCache):
|
||||||
expression = models.Expression(output_field=models.DateTimeField())
|
expression = models.Expression(output_field=models.DateTimeField())
|
||||||
for converter in (connection.ops.get_db_converters(expression) +
|
for converter in (connection.ops.get_db_converters(expression) +
|
||||||
expression.get_db_converters(connection)):
|
expression.get_db_converters(connection)):
|
||||||
current_expires = converter(current_expires, expression, connection, {})
|
if func_supports_parameter(converter, 'context'): # RemovedInDjango30Warning
|
||||||
|
current_expires = converter(current_expires, expression, connection, {})
|
||||||
|
else:
|
||||||
|
current_expires = converter(current_expires, expression, connection)
|
||||||
|
|
||||||
exp = connection.ops.adapt_datetimefield_value(exp)
|
exp = connection.ops.adapt_datetimefield_value(exp)
|
||||||
if result and (mode == 'set' or (mode == 'add' and current_expires < now)):
|
if result and (mode == 'set' or (mode == 'add' and current_expires < now)):
|
||||||
|
|
|
@ -534,7 +534,7 @@ class BaseDatabaseOperations:
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def convert_durationfield_value(self, value, expression, connection, context):
|
def convert_durationfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = str(decimal.Decimal(value) / decimal.Decimal(1000000))
|
value = str(decimal.Decimal(value) / decimal.Decimal(1000000))
|
||||||
value = parse_duration(value)
|
value = parse_duration(value)
|
||||||
|
|
|
@ -221,23 +221,23 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
converters.append(self.convert_uuidfield_value)
|
converters.append(self.convert_uuidfield_value)
|
||||||
return converters
|
return converters
|
||||||
|
|
||||||
def convert_textfield_value(self, value, expression, connection, context):
|
def convert_textfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = force_text(value)
|
value = force_text(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_booleanfield_value(self, value, expression, connection, context):
|
def convert_booleanfield_value(self, value, expression, connection):
|
||||||
if value in (0, 1):
|
if value in (0, 1):
|
||||||
value = bool(value)
|
value = bool(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_datetimefield_value(self, value, expression, connection, context):
|
def convert_datetimefield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
value = timezone.make_aware(value, self.connection.timezone)
|
value = timezone.make_aware(value, self.connection.timezone)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_uuidfield_value(self, value, expression, connection, context):
|
def convert_uuidfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = uuid.UUID(value)
|
value = uuid.UUID(value)
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -165,17 +165,17 @@ END;
|
||||||
converters.append(self.convert_empty_values)
|
converters.append(self.convert_empty_values)
|
||||||
return converters
|
return converters
|
||||||
|
|
||||||
def convert_textfield_value(self, value, expression, connection, context):
|
def convert_textfield_value(self, value, expression, connection):
|
||||||
if isinstance(value, Database.LOB):
|
if isinstance(value, Database.LOB):
|
||||||
value = value.read()
|
value = value.read()
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_binaryfield_value(self, value, expression, connection, context):
|
def convert_binaryfield_value(self, value, expression, connection):
|
||||||
if isinstance(value, Database.LOB):
|
if isinstance(value, Database.LOB):
|
||||||
value = force_bytes(value.read())
|
value = force_bytes(value.read())
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_booleanfield_value(self, value, expression, connection, context):
|
def convert_booleanfield_value(self, value, expression, connection):
|
||||||
if value in (0, 1):
|
if value in (0, 1):
|
||||||
value = bool(value)
|
value = bool(value)
|
||||||
return value
|
return value
|
||||||
|
@ -184,28 +184,28 @@ END;
|
||||||
# DATE and TIMESTAMP columns, but Django wants to see a
|
# DATE and TIMESTAMP columns, but Django wants to see a
|
||||||
# python datetime.date, .time, or .datetime.
|
# python datetime.date, .time, or .datetime.
|
||||||
|
|
||||||
def convert_datetimefield_value(self, value, expression, connection, context):
|
def convert_datetimefield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
value = timezone.make_aware(value, self.connection.timezone)
|
value = timezone.make_aware(value, self.connection.timezone)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_datefield_value(self, value, expression, connection, context):
|
def convert_datefield_value(self, value, expression, connection):
|
||||||
if isinstance(value, Database.Timestamp):
|
if isinstance(value, Database.Timestamp):
|
||||||
value = value.date()
|
value = value.date()
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_timefield_value(self, value, expression, connection, context):
|
def convert_timefield_value(self, value, expression, connection):
|
||||||
if isinstance(value, Database.Timestamp):
|
if isinstance(value, Database.Timestamp):
|
||||||
value = value.time()
|
value = value.time()
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_uuidfield_value(self, value, expression, connection, context):
|
def convert_uuidfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = uuid.UUID(value)
|
value = uuid.UUID(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_empty_values(self, value, expression, connection, context):
|
def convert_empty_values(self, value, expression, connection):
|
||||||
# Oracle stores empty strings as null. We need to undo this in
|
# Oracle stores empty strings as null. We need to undo this in
|
||||||
# order to adhere to the Django convention of using the empty
|
# order to adhere to the Django convention of using the empty
|
||||||
# string instead of null, but only if the field accepts the
|
# string instead of null, but only if the field accepts the
|
||||||
|
|
|
@ -212,7 +212,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
converters.append(self.convert_booleanfield_value)
|
converters.append(self.convert_booleanfield_value)
|
||||||
return converters
|
return converters
|
||||||
|
|
||||||
def convert_datetimefield_value(self, value, expression, connection, context):
|
def convert_datetimefield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if not isinstance(value, datetime.datetime):
|
if not isinstance(value, datetime.datetime):
|
||||||
value = parse_datetime(value)
|
value = parse_datetime(value)
|
||||||
|
@ -220,30 +220,30 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
value = timezone.make_aware(value, self.connection.timezone)
|
value = timezone.make_aware(value, self.connection.timezone)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_datefield_value(self, value, expression, connection, context):
|
def convert_datefield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if not isinstance(value, datetime.date):
|
if not isinstance(value, datetime.date):
|
||||||
value = parse_date(value)
|
value = parse_date(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_timefield_value(self, value, expression, connection, context):
|
def convert_timefield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
if not isinstance(value, datetime.time):
|
if not isinstance(value, datetime.time):
|
||||||
value = parse_time(value)
|
value = parse_time(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_decimalfield_value(self, value, expression, connection, context):
|
def convert_decimalfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = expression.output_field.format_number(value)
|
value = expression.output_field.format_number(value)
|
||||||
value = backend_utils.typecast_decimal(value)
|
value = backend_utils.typecast_decimal(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_uuidfield_value(self, value, expression, connection, context):
|
def convert_uuidfield_value(self, value, expression, connection):
|
||||||
if value is not None:
|
if value is not None:
|
||||||
value = uuid.UUID(value)
|
value = uuid.UUID(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def convert_booleanfield_value(self, value, expression, connection, context):
|
def convert_booleanfield_value(self, value, expression, connection):
|
||||||
return bool(value) if value in (1, 0) else value
|
return bool(value) if value in (1, 0) else value
|
||||||
|
|
||||||
def bulk_insert_sql(self, fields, placeholder_rows):
|
def bulk_insert_sql(self, fields, placeholder_rows):
|
||||||
|
|
|
@ -73,7 +73,7 @@ class Count(Aggregate):
|
||||||
def _get_repr_options(self):
|
def _get_repr_options(self):
|
||||||
return {'distinct': self.extra['distinct'] != ''}
|
return {'distinct': self.extra['distinct'] != ''}
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return 0
|
return 0
|
||||||
return int(value)
|
return int(value)
|
||||||
|
@ -99,7 +99,7 @@ class StdDev(Aggregate):
|
||||||
def _get_repr_options(self):
|
def _get_repr_options(self):
|
||||||
return {'sample': self.function == 'STDDEV_SAMP'}
|
return {'sample': self.function == 'STDDEV_SAMP'}
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
return float(value)
|
return float(value)
|
||||||
|
@ -129,7 +129,7 @@ class Variance(Aggregate):
|
||||||
def _get_repr_options(self):
|
def _get_repr_options(self):
|
||||||
return {'sample': self.function == 'VAR_SAMP'}
|
return {'sample': self.function == 'VAR_SAMP'}
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
return float(value)
|
return float(value)
|
||||||
|
|
|
@ -261,7 +261,7 @@ class BaseExpression:
|
||||||
raise FieldError('Expression contains mixed types. You must set output_field.')
|
raise FieldError('Expression contains mixed types. You must set output_field.')
|
||||||
return output_field
|
return output_field
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
"""
|
"""
|
||||||
Expressions provide their own converters because users have the option
|
Expressions provide their own converters because users have the option
|
||||||
of manually specifying the output_field which may be a different type
|
of manually specifying the output_field which may be a different type
|
||||||
|
|
|
@ -939,7 +939,7 @@ class ForeignKey(ForeignObject):
|
||||||
def db_parameters(self, connection):
|
def db_parameters(self, connection):
|
||||||
return {"type": self.db_type(connection), "check": self.db_check(connection)}
|
return {"type": self.db_type(connection), "check": self.db_check(connection)}
|
||||||
|
|
||||||
def convert_empty_strings(self, value, expression, connection, context):
|
def convert_empty_strings(self, value, expression, connection):
|
||||||
if (not value) and isinstance(value, str):
|
if (not value) and isinstance(value, str):
|
||||||
return None
|
return None
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -198,7 +198,7 @@ class TruncBase(TimezoneMixin, Transform):
|
||||||
))
|
))
|
||||||
return copy
|
return copy
|
||||||
|
|
||||||
def convert_value(self, value, expression, connection, context):
|
def convert_value(self, value, expression, connection):
|
||||||
if isinstance(self.output_field, DateTimeField):
|
if isinstance(self.output_field, DateTimeField):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
if value is None:
|
if value is None:
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import collections
|
import collections
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
from django.core.exceptions import EmptyResultSet, FieldError
|
from django.core.exceptions import EmptyResultSet, FieldError
|
||||||
|
@ -12,6 +13,8 @@ from django.db.models.sql.constants import (
|
||||||
from django.db.models.sql.query import Query, get_order_dir
|
from django.db.models.sql.query import Query, get_order_dir
|
||||||
from django.db.transaction import TransactionManagementError
|
from django.db.transaction import TransactionManagementError
|
||||||
from django.db.utils import DatabaseError, NotSupportedError
|
from django.db.utils import DatabaseError, NotSupportedError
|
||||||
|
from django.utils.deprecation import RemovedInDjango30Warning
|
||||||
|
from django.utils.inspect import func_supports_parameter
|
||||||
|
|
||||||
FORCE = object()
|
FORCE = object()
|
||||||
|
|
||||||
|
@ -926,7 +929,18 @@ class SQLCompiler:
|
||||||
for pos, (convs, expression) in converters.items():
|
for pos, (convs, expression) in converters.items():
|
||||||
value = row[pos]
|
value = row[pos]
|
||||||
for converter in convs:
|
for converter in convs:
|
||||||
value = converter(value, expression, self.connection, self.query.context)
|
if func_supports_parameter(converter, 'context'):
|
||||||
|
warnings.warn(
|
||||||
|
'Remove the context parameter from %s.%s(). Support for it '
|
||||||
|
'will be removed in Django 3.0.' % (
|
||||||
|
converter.__self__.__class__.__name__,
|
||||||
|
converter.__name__,
|
||||||
|
),
|
||||||
|
RemovedInDjango30Warning,
|
||||||
|
)
|
||||||
|
value = converter(value, expression, self.connection, {})
|
||||||
|
else:
|
||||||
|
value = converter(value, expression, self.connection)
|
||||||
row[pos] = value
|
row[pos] = value
|
||||||
return tuple(row)
|
return tuple(row)
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ def get_field_names_from_opts(opts):
|
||||||
class RawQuery:
|
class RawQuery:
|
||||||
"""A single raw SQL query."""
|
"""A single raw SQL query."""
|
||||||
|
|
||||||
def __init__(self, sql, using, params=None, context=None):
|
def __init__(self, sql, using, params=None):
|
||||||
self.params = params or ()
|
self.params = params or ()
|
||||||
self.sql = sql
|
self.sql = sql
|
||||||
self.using = using
|
self.using = using
|
||||||
|
@ -57,10 +57,9 @@ class RawQuery:
|
||||||
self.low_mark, self.high_mark = 0, None # Used for offset/limit
|
self.low_mark, self.high_mark = 0, None # Used for offset/limit
|
||||||
self.extra_select = {}
|
self.extra_select = {}
|
||||||
self.annotation_select = {}
|
self.annotation_select = {}
|
||||||
self.context = context or {}
|
|
||||||
|
|
||||||
def clone(self, using):
|
def clone(self, using):
|
||||||
return RawQuery(self.sql, using, params=self.params, context=self.context.copy())
|
return RawQuery(self.sql, using, params=self.params)
|
||||||
|
|
||||||
def get_columns(self):
|
def get_columns(self):
|
||||||
if self.cursor is None:
|
if self.cursor is None:
|
||||||
|
@ -200,8 +199,6 @@ class Query:
|
||||||
# load.
|
# load.
|
||||||
self.deferred_loading = (frozenset(), True)
|
self.deferred_loading = (frozenset(), True)
|
||||||
|
|
||||||
self.context = {}
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extra(self):
|
def extra(self):
|
||||||
if self._extra is None:
|
if self._extra is None:
|
||||||
|
@ -334,15 +331,8 @@ class Query:
|
||||||
obj.__dict__.update(kwargs)
|
obj.__dict__.update(kwargs)
|
||||||
if hasattr(obj, '_setup_query'):
|
if hasattr(obj, '_setup_query'):
|
||||||
obj._setup_query()
|
obj._setup_query()
|
||||||
obj.context = self.context.copy()
|
|
||||||
return obj
|
return obj
|
||||||
|
|
||||||
def add_context(self, key, value):
|
|
||||||
self.context[key] = value
|
|
||||||
|
|
||||||
def get_context(self, key, default=None):
|
|
||||||
return self.context.get(key, default)
|
|
||||||
|
|
||||||
def relabeled_clone(self, change_map):
|
def relabeled_clone(self, change_map):
|
||||||
clone = self.clone()
|
clone = self.clone()
|
||||||
clone.change_aliases(change_map)
|
clone.change_aliases(change_map)
|
||||||
|
|
|
@ -512,7 +512,7 @@ instances::
|
||||||
class HandField(models.Field):
|
class HandField(models.Field):
|
||||||
# ...
|
# ...
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
return parse_hand(value)
|
return parse_hand(value)
|
||||||
|
|
|
@ -23,6 +23,9 @@ details on these changes.
|
||||||
|
|
||||||
* ``HttpRequest.xreadlines()`` will be removed.
|
* ``HttpRequest.xreadlines()`` will be removed.
|
||||||
|
|
||||||
|
* Support for the ``context`` argument of ``Field.from_db_value()`` and
|
||||||
|
``Expression.convert_value()`` will be removed.
|
||||||
|
|
||||||
.. _deprecation-removed-in-2.1:
|
.. _deprecation-removed-in-2.1:
|
||||||
|
|
||||||
2.1
|
2.1
|
||||||
|
|
|
@ -714,7 +714,7 @@ calling the appropriate methods on the wrapped expression.
|
||||||
clone.expression = self.expression.relabeled_clone(change_map)
|
clone.expression = self.expression.relabeled_clone(change_map)
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
.. method:: convert_value(value, expression, connection, context)
|
.. method:: convert_value(value, expression, connection)
|
||||||
|
|
||||||
A hook allowing the expression to coerce ``value`` into a more
|
A hook allowing the expression to coerce ``value`` into a more
|
||||||
appropriate type.
|
appropriate type.
|
||||||
|
|
|
@ -1797,7 +1797,7 @@ Field API reference
|
||||||
|
|
||||||
When loading data, :meth:`from_db_value` is used:
|
When loading data, :meth:`from_db_value` is used:
|
||||||
|
|
||||||
.. method:: from_db_value(value, expression, connection, context)
|
.. method:: from_db_value(value, expression, connection)
|
||||||
|
|
||||||
Converts a value as returned by the database to a Python object. It is
|
Converts a value as returned by the database to a Python object. It is
|
||||||
the reverse of :meth:`get_prep_value`.
|
the reverse of :meth:`get_prep_value`.
|
||||||
|
|
|
@ -564,6 +564,22 @@ Miscellaneous
|
||||||
Features deprecated in 2.0
|
Features deprecated in 2.0
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
|
``context`` argument of ``Field.from_db_value()`` and ``Expression.convert_value()``
|
||||||
|
------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
The ``context`` argument of ``Field.from_db_value()`` and
|
||||||
|
``Expression.convert_value()`` is unused as it's always an empty dictionary.
|
||||||
|
The signature of both methods is now::
|
||||||
|
|
||||||
|
(self, value, expression, connection)
|
||||||
|
|
||||||
|
instead of::
|
||||||
|
|
||||||
|
(self, value, expression, connection, context)
|
||||||
|
|
||||||
|
Support for the old signature in custom fields and expressions remains until
|
||||||
|
Django 3.0.
|
||||||
|
|
||||||
Miscellaneous
|
Miscellaneous
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
|
|
|
@ -40,7 +40,7 @@ class MyAutoField(models.CharField):
|
||||||
value = MyWrapper(value)
|
value = MyWrapper(value)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
if not value:
|
if not value:
|
||||||
return
|
return
|
||||||
return MyWrapper(value)
|
return MyWrapper(value)
|
||||||
|
|
|
@ -17,7 +17,7 @@ class CashField(models.DecimalField):
|
||||||
kwargs['decimal_places'] = 2
|
kwargs['decimal_places'] = 2
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
cash = Cash(value)
|
cash = Cash(value)
|
||||||
cash.vendor = connection.vendor
|
cash.vendor = connection.vendor
|
||||||
return cash
|
return cash
|
||||||
|
@ -28,3 +28,12 @@ class CashModel(models.Model):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.cash)
|
return str(self.cash)
|
||||||
|
|
||||||
|
|
||||||
|
class CashFieldDeprecated(CashField):
|
||||||
|
def from_db_value(self, value, expression, connection, context):
|
||||||
|
return super().from_db_value(value, expression, connection)
|
||||||
|
|
||||||
|
|
||||||
|
class CashModelDeprecated(models.Model):
|
||||||
|
cash = CashFieldDeprecated()
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from .models import Cash, CashModelDeprecated
|
||||||
|
|
||||||
|
|
||||||
|
class FromDBValueDeprecationTests(TestCase):
|
||||||
|
|
||||||
|
def test_deprecation(self):
|
||||||
|
CashModelDeprecated.objects.create(cash='12.50')
|
||||||
|
with warnings.catch_warnings(record=True) as warns:
|
||||||
|
warnings.simplefilter('always')
|
||||||
|
instance = CashModelDeprecated.objects.get()
|
||||||
|
self.assertIsInstance(instance.cash, Cash)
|
||||||
|
self.assertEqual(len(warns), 1)
|
||||||
|
msg = str(warns[0].message)
|
||||||
|
self.assertEqual(
|
||||||
|
msg,
|
||||||
|
'Remove the context parameter from CashFieldDeprecated.from_db_value(). '
|
||||||
|
'Support for it will be removed in Django 3.0.'
|
||||||
|
)
|
|
@ -18,7 +18,7 @@ class Tag:
|
||||||
|
|
||||||
class TagField(models.SmallIntegerField):
|
class TagField(models.SmallIntegerField):
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
if value is None:
|
if value is None:
|
||||||
return value
|
return value
|
||||||
return Tag(int(value))
|
return Tag(int(value))
|
||||||
|
|
|
@ -124,7 +124,7 @@ class TeamField(models.CharField):
|
||||||
return value
|
return value
|
||||||
return Team(value)
|
return Team(value)
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection, context):
|
def from_db_value(self, value, expression, connection):
|
||||||
return Team(value)
|
return Team(value)
|
||||||
|
|
||||||
def value_to_string(self, obj):
|
def value_to_string(self, obj):
|
||||||
|
|
Loading…
Reference in New Issue