|
@@ -144,8 +144,18 @@ class BaseExpression:
|
|
|
if output_field is not None:
|
|
|
self.output_field = output_field
|
|
|
|
|
|
+ def __getstate__(self):
|
|
|
+ # This method required only for Python 3.4.
|
|
|
+ state = self.__dict__.copy()
|
|
|
+ state.pop('convert_value', None)
|
|
|
+ return state
|
|
|
+
|
|
|
def get_db_converters(self, connection):
|
|
|
- return [self.convert_value] + self.output_field.get_db_converters(connection)
|
|
|
+ return (
|
|
|
+ []
|
|
|
+ if self.convert_value is self._convert_value_noop else
|
|
|
+ [self.convert_value]
|
|
|
+ ) + self.output_field.get_db_converters(connection)
|
|
|
|
|
|
def get_source_expressions(self):
|
|
|
return []
|
|
@@ -274,7 +284,12 @@ class BaseExpression:
|
|
|
raise FieldError('Expression contains mixed types. You must set output_field.')
|
|
|
return output_field
|
|
|
|
|
|
- def convert_value(self, value, expression, connection):
|
|
|
+ @staticmethod
|
|
|
+ def _convert_value_noop(value, expression, connection):
|
|
|
+ return value
|
|
|
+
|
|
|
+ @cached_property
|
|
|
+ def convert_value(self):
|
|
|
"""
|
|
|
Expressions provide their own converters because users have the option
|
|
|
of manually specifying the output_field which may be a different type
|
|
@@ -282,15 +297,13 @@ class BaseExpression:
|
|
|
"""
|
|
|
field = self.output_field
|
|
|
internal_type = field.get_internal_type()
|
|
|
- if value is None:
|
|
|
- return value
|
|
|
- elif internal_type == 'FloatField':
|
|
|
- return float(value)
|
|
|
+ if internal_type == 'FloatField':
|
|
|
+ return lambda value, expression, connection: None if value is None else float(value)
|
|
|
elif internal_type.endswith('IntegerField'):
|
|
|
- return int(value)
|
|
|
+ return lambda value, expression, connection: None if value is None else int(value)
|
|
|
elif internal_type == 'DecimalField':
|
|
|
- return Decimal(value)
|
|
|
- return value
|
|
|
+ return lambda value, expression, connection: None if value is None else Decimal(value)
|
|
|
+ return self._convert_value_noop
|
|
|
|
|
|
def get_lookup(self, lookup):
|
|
|
return self.output_field.get_lookup(lookup)
|