diff --git a/django/contrib/gis/db/backends/oracle/operations.py b/django/contrib/gis/db/backends/oracle/operations.py index 9d405056322..8709202cd23 100644 --- a/django/contrib/gis/db/backends/oracle/operations.py +++ b/django/contrib/gis/db/backends/oracle/operations.py @@ -127,7 +127,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations): converters.append(self.convert_geometry) return converters - def convert_geometry(self, value, expression, context): + def convert_geometry(self, value, expression, connection, context): if value: value = Geometry(value) if 'transformed_srid' in context: diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py index 73adb02b052..6c89849cafb 100644 --- a/django/contrib/gis/db/backends/spatialite/operations.py +++ b/django/contrib/gis/db/backends/spatialite/operations.py @@ -262,7 +262,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations): converters.append(self.convert_geometry) return converters - def convert_geometry(self, value, expression, context): + def convert_geometry(self, value, expression, connection, context): if value: value = Geometry(value) if 'transformed_srid' in context: diff --git a/django/contrib/gis/db/models/aggregates.py b/django/contrib/gis/db/models/aggregates.py index 60954951e67..7458b2bdeb7 100644 --- a/django/contrib/gis/db/models/aggregates.py +++ b/django/contrib/gis/db/models/aggregates.py @@ -29,7 +29,7 @@ class GeoAggregate(Aggregate): raise ValueError('Geospatial aggregates only allowed on geometry fields.') return c - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): return connection.ops.convert_geom(value, self.output_field) @@ -44,7 +44,7 @@ class Extent(GeoAggregate): def __init__(self, expression, **extra): super(Extent, self).__init__(expression, output_field=ExtentField(), **extra) - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): return connection.ops.convert_extent(value, context.get('transformed_srid')) @@ -55,7 +55,7 @@ class Extent3D(GeoAggregate): def __init__(self, expression, **extra): super(Extent3D, self).__init__(expression, output_field=ExtentField(), **extra) - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): return connection.ops.convert_extent3d(value, context.get('transformed_srid')) diff --git a/django/contrib/gis/db/models/fields.py b/django/contrib/gis/db/models/fields.py index df26b8b9f8b..1d95ce7be70 100644 --- a/django/contrib/gis/db/models/fields.py +++ b/django/contrib/gis/db/models/fields.py @@ -219,7 +219,7 @@ class GeometryField(GeoSelectFormatMixin, Field): else: return geom - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): if value and not isinstance(value, Geometry): value = Geometry(value) return value diff --git a/django/contrib/gis/db/models/sql/conversion.py b/django/contrib/gis/db/models/sql/conversion.py index 19e7b5bfbd5..28e601613e3 100644 --- a/django/contrib/gis/db/models/sql/conversion.py +++ b/django/contrib/gis/db/models/sql/conversion.py @@ -23,7 +23,7 @@ class AreaField(BaseField): def __init__(self, area_att): self.area_att = area_att - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): if value is not None: value = Area(**{self.area_att: value}) return value @@ -37,7 +37,7 @@ class DistanceField(BaseField): def __init__(self, distance_att): self.distance_att = distance_att - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): if value is not None: value = Distance(**{self.distance_att: value}) return value @@ -54,7 +54,7 @@ class GeomField(GeoSelectFormatMixin, BaseField): # Hacky marker for get_db_converters() geom_type = None - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): if value is not None: value = Geometry(value) return value @@ -71,5 +71,5 @@ class GMLField(BaseField): def get_internal_type(self): return 'GMLField' - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): return value diff --git a/django/db/backends/base/operations.py b/django/db/backends/base/operations.py index 870edde3822..e7cf6243dc1 100644 --- a/django/db/backends/base/operations.py +++ b/django/db/backends/base/operations.py @@ -519,7 +519,7 @@ class BaseDatabaseOperations(object): """ return [] - def convert_durationfield_value(self, value, expression, context): + def convert_durationfield_value(self, value, expression, connection, context): if value is not None: value = str(decimal.Decimal(value) / decimal.Decimal(1000000)) value = parse_duration(value) diff --git a/django/db/backends/mysql/operations.py b/django/db/backends/mysql/operations.py index 7edc13b3ffa..fd468cb182a 100644 --- a/django/db/backends/mysql/operations.py +++ b/django/db/backends/mysql/operations.py @@ -184,17 +184,17 @@ class DatabaseOperations(BaseDatabaseOperations): converters.append(self.convert_textfield_value) return converters - def convert_booleanfield_value(self, value, expression, context): + def convert_booleanfield_value(self, value, expression, connection, context): if value in (0, 1): value = bool(value) return value - def convert_uuidfield_value(self, value, expression, context): + def convert_uuidfield_value(self, value, expression, connection, context): if value is not None: value = uuid.UUID(value) return value - def convert_textfield_value(self, value, expression, context): + def convert_textfield_value(self, value, expression, connection, context): if value is not None: value = force_text(value) return value diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py index 1ba49909d82..02fd6fcc7d5 100644 --- a/django/db/backends/oracle/operations.py +++ b/django/db/backends/oracle/operations.py @@ -172,7 +172,7 @@ WHEN (new.%(col_name)s IS NULL) converters.append(self.convert_empty_values) return converters - def convert_empty_values(self, value, expression, context): + def convert_empty_values(self, value, expression, connection, context): # Oracle stores empty strings as null. We need to undo this in # order to adhere to the Django convention of using the empty # string instead of null, but only if the field accepts the @@ -184,17 +184,17 @@ WHEN (new.%(col_name)s IS NULL) value = b'' return value - def convert_textfield_value(self, value, expression, context): + def convert_textfield_value(self, value, expression, connection, context): if isinstance(value, Database.LOB): value = force_text(value.read()) return value - def convert_binaryfield_value(self, value, expression, context): + def convert_binaryfield_value(self, value, expression, connection, context): if isinstance(value, Database.LOB): value = force_bytes(value.read()) return value - def convert_booleanfield_value(self, value, expression, context): + def convert_booleanfield_value(self, value, expression, connection, context): if value in (1, 0): value = bool(value) return value @@ -202,16 +202,16 @@ WHEN (new.%(col_name)s IS NULL) # cx_Oracle always returns datetime.datetime objects for # DATE and TIMESTAMP columns, but Django wants to see a # python datetime.date, .time, or .datetime. - def convert_datefield_value(self, value, expression, context): + def convert_datefield_value(self, value, expression, connection, context): if isinstance(value, Database.Timestamp): return value.date() - def convert_timefield_value(self, value, expression, context): + def convert_timefield_value(self, value, expression, connection, context): if isinstance(value, Database.Timestamp): value = value.time() return value - def convert_uuidfield_value(self, value, expression, context): + def convert_uuidfield_value(self, value, expression, connection, context): if value is not None: value = uuid.UUID(value) return value diff --git a/django/db/backends/sqlite3/operations.py b/django/db/backends/sqlite3/operations.py index 5d974f36dfd..f7e2c64da1b 100644 --- a/django/db/backends/sqlite3/operations.py +++ b/django/db/backends/sqlite3/operations.py @@ -153,25 +153,25 @@ class DatabaseOperations(BaseDatabaseOperations): converters.append(self.convert_uuidfield_value) return converters - def convert_decimalfield_value(self, value, expression, context): + def convert_decimalfield_value(self, value, expression, connection, context): return backend_utils.typecast_decimal(expression.output_field.format_number(value)) - def convert_datefield_value(self, value, expression, context): + def convert_datefield_value(self, value, expression, connection, context): if value is not None and not isinstance(value, datetime.date): value = parse_date(value) return value - def convert_datetimefield_value(self, value, expression, context): + def convert_datetimefield_value(self, value, expression, connection, context): if value is not None and not isinstance(value, datetime.datetime): value = parse_datetime_with_timezone_support(value) return value - def convert_timefield_value(self, value, expression, context): + def convert_timefield_value(self, value, expression, connection, context): if value is not None and not isinstance(value, datetime.time): value = parse_time(value) return value - def convert_uuidfield_value(self, value, expression, context): + def convert_uuidfield_value(self, value, expression, connection, context): if value is not None: value = uuid.UUID(value) return value diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py index 01ab61f71af..b51fe5635ac 100644 --- a/django/db/models/aggregates.py +++ b/django/db/models/aggregates.py @@ -77,7 +77,7 @@ class Avg(Aggregate): def __init__(self, expression, **extra): super(Avg, self).__init__(expression, output_field=FloatField(), **extra) - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): if value is None: return value return float(value) @@ -101,7 +101,7 @@ class Count(Aggregate): 'False' if self.extra['distinct'] == '' else 'True', ) - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): if value is None: return 0 return int(value) @@ -131,7 +131,7 @@ class StdDev(Aggregate): 'False' if self.function == 'STDDEV_POP' else 'True', ) - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): if value is None: return value return float(value) @@ -156,7 +156,7 @@ class Variance(Aggregate): 'False' if self.function == 'VAR_POP' else 'True', ) - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): if value is None: return value return float(value) diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py index 2e41803a1a5..00a64248869 100644 --- a/django/db/models/expressions.py +++ b/django/db/models/expressions.py @@ -252,7 +252,7 @@ class BaseExpression(object): raise FieldError( "Expression contains mixed types. You must set output_field") - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): """ Expressions provide their own converters because users have the option of manually specifying the output_field which may be a different type @@ -804,7 +804,7 @@ class Date(ExpressionNode): copy.lookup_type = self.lookup_type return copy - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): if isinstance(value, datetime.datetime): value = value.date() return value @@ -856,7 +856,7 @@ class DateTime(ExpressionNode): copy.tzname = self.tzname return copy - def convert_value(self, value, connection, context): + def convert_value(self, value, expression, connection, context): if settings.USE_TZ: if value is None: raise ValueError( diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py index 3410e5c994f..c07a01ced9c 100644 --- a/django/db/models/fields/related.py +++ b/django/db/models/fields/related.py @@ -1991,7 +1991,7 @@ class ForeignKey(ForeignObject): def db_parameters(self, connection): return {"type": self.db_type(connection), "check": []} - def convert_empty_strings(self, value, connection, context): + def convert_empty_strings(self, value, expression, connection, context): if (not value) and isinstance(value, six.string_types): return None return value diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 5c1dcf4f051..136d066ec35 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -762,17 +762,15 @@ class SQLCompiler(object): backend_converters = self.connection.ops.get_db_converters(expression) field_converters = expression.get_db_converters(self.connection) if backend_converters or field_converters: - converters[i] = (backend_converters, field_converters, expression) + converters[i] = (backend_converters + field_converters, expression) return converters def apply_converters(self, row, converters): row = list(row) - for pos, (backend_converters, field_converters, field) in converters.items(): + for pos, (convs, expression) in converters.items(): value = row[pos] - for converter in backend_converters: - value = converter(value, field, self.query.context) - for converter in field_converters: - value = converter(value, self.connection, self.query.context) + for converter in convs: + value = converter(value, expression, self.connection, self.query.context) row[pos] = value return tuple(row) diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt index f35cc41d3df..d62706ca3a9 100644 --- a/docs/howto/custom-model-fields.txt +++ b/docs/howto/custom-model-fields.txt @@ -483,7 +483,7 @@ instances:: class HandField(models.Field): # ... - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): if value is None: return value return parse_hand(value) diff --git a/docs/ref/models/expressions.txt b/docs/ref/models/expressions.txt index f170af8510b..0224a21e54c 100644 --- a/docs/ref/models/expressions.txt +++ b/docs/ref/models/expressions.txt @@ -416,7 +416,7 @@ calling the appropriate methods on the wrapped expression. clone.expression = self.expression.relabeled_clone(change_map) return clone - .. method:: convert_value(self, value, connection, context) + .. method:: convert_value(self, value, expression, connection, context) A hook allowing the expression to coerce ``value`` into a more appropriate type. diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt index ee82c315a1e..87029876303 100644 --- a/docs/ref/models/fields.txt +++ b/docs/ref/models/fields.txt @@ -1679,7 +1679,7 @@ Field API reference When loading data, :meth:`from_db_value` is used: - .. method:: from_db_value(value, connection, context) + .. method:: from_db_value(value, expression, connection, context) .. versionadded:: 1.8 diff --git a/tests/custom_pk/fields.py b/tests/custom_pk/fields.py index bf349545e52..3779fc6c433 100644 --- a/tests/custom_pk/fields.py +++ b/tests/custom_pk/fields.py @@ -43,7 +43,7 @@ class MyAutoField(models.CharField): value = MyWrapper(value) return value - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): if not value: return return MyWrapper(value) diff --git a/tests/from_db_value/models.py b/tests/from_db_value/models.py index 6a06c832ea9..aa62b1f5672 100644 --- a/tests/from_db_value/models.py +++ b/tests/from_db_value/models.py @@ -18,7 +18,7 @@ class CashField(models.DecimalField): kwargs['decimal_places'] = 2 super(CashField, self).__init__(**kwargs) - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): cash = Cash(value) cash.vendor = connection.vendor return cash diff --git a/tests/serializers/models.py b/tests/serializers/models.py index b2864b1c717..08dc8608219 100644 --- a/tests/serializers/models.py +++ b/tests/serializers/models.py @@ -112,7 +112,7 @@ class TeamField(models.CharField): return value return Team(value) - def from_db_value(self, value, connection, context): + def from_db_value(self, value, expression, connection, context): return Team(value) def value_to_string(self, obj):