Refs #28459 -- Improved performance of BaseExpression.convert_value().

This commit is contained in:
Sergey Fedoseev 2017-08-12 03:34:50 +05:00 committed by Tim Graham
parent d04b324969
commit 47ccefeada
1 changed files with 22 additions and 9 deletions

View File

@ -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)