mirror of
				https://github.com/django/django.git
				synced 2025-10-26 07:06:08 +00:00 
			
		
		
		
	Update converters to take a consistent set of parameters.
As suggested by Anssi. This has the slightly strange side effect of passing the expression to Expression.convert_value has the expression passed back to it, but it allows more complex patterns of expressions.
This commit is contained in:
		| @@ -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: | ||||
|   | ||||
| @@ -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: | ||||
|   | ||||
| @@ -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')) | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -512,7 +512,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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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( | ||||
|   | ||||
| @@ -2064,7 +2064,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 | ||||
|   | ||||
| @@ -760,17 +760,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) | ||||
|  | ||||
|   | ||||
| @@ -477,7 +477,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) | ||||
|   | ||||
| @@ -412,7 +412,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. | ||||
|   | ||||
| @@ -1630,7 +1630,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 | ||||
|  | ||||
|   | ||||
| @@ -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) | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user