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: if output_field is not None:
self.output_field = output_field 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): 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): def get_source_expressions(self):
return [] return []
@ -274,7 +284,12 @@ 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): @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 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
@ -282,15 +297,13 @@ class BaseExpression:
""" """
field = self.output_field field = self.output_field
internal_type = field.get_internal_type() internal_type = field.get_internal_type()
if value is None: if internal_type == 'FloatField':
return value return lambda value, expression, connection: None if value is None else float(value)
elif internal_type == 'FloatField':
return float(value)
elif internal_type.endswith('IntegerField'): 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': elif internal_type == 'DecimalField':
return Decimal(value) return lambda value, expression, connection: None if value is None else Decimal(value)
return value return self._convert_value_noop
def get_lookup(self, lookup): def get_lookup(self, lookup):
return self.output_field.get_lookup(lookup) return self.output_field.get_lookup(lookup)